From ale at codespeak.net Mon Aug 1 14:29:50 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 1 Aug 2005 14:29:50 +0200 (CEST) Subject: [pypy-svn] r15496 - pypy/extradoc/sprintinfo Message-ID: <20050801122950.7E06027B59@code1.codespeak.net> Author: ale Date: Mon Aug 1 14:29:49 2005 New Revision: 15496 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: my details for the Heidelberg sprint Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Mon Aug 1 14:29:49 2005 @@ -25,4 +25,5 @@ Ludovic Aubry ? ? Anders Chrigstroem ? ? Christian Tismer ? ? +Anders Lehmann 21st-29th Aug =================== ============== ===================== From rxe at codespeak.net Tue Aug 2 10:39:13 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Tue, 2 Aug 2005 10:39:13 +0200 (CEST) Subject: [pypy-svn] r15502 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050802083913.7529127B57@code1.codespeak.net> Author: rxe Date: Tue Aug 2 10:39:11 2005 New Revision: 15502 Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: oops - late last night sprint checkin went awry. Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Tue Aug 2 10:39:11 2005 @@ -63,7 +63,7 @@ assert result == True def testfn(): l1 = [] - return l1 == None + return l1 is None fn = compile_function(testfn, []) result = fn() assert result == False From ale at codespeak.net Tue Aug 2 12:30:15 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 2 Aug 2005 12:30:15 +0200 (CEST) Subject: [pypy-svn] r15503 - in pypy/dist/pypy: interpreter/pyparser/test module/_codecs Message-ID: <20050802103015.7BE7327B52@code1.codespeak.net> Author: ale Date: Tue Aug 2 12:30:13 2005 New Revision: 15503 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_parsestring.py pypy/dist/pypy/module/_codecs/app_codecs.py Log: The skipped test in test_parsestring passes. For some reason you cant ask isinstance(,(int,long)) at interpreterlevel ? Changed the isinstance to only ask for ints. enabled the test Modified: pypy/dist/pypy/interpreter/pyparser/test/test_parsestring.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_parsestring.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_parsestring.py Tue Aug 2 12:30:13 2005 @@ -43,7 +43,7 @@ assert ret == eval("# -*- coding: koi8-u -*-\nu'\x81'") def test_simple_enc_roundtrip(self): - py.test.skip("crashes in app_codecs, but when cheating using .encode at interp-level passes?!") + #py.test.skip("crashes in app_codecs, but when cheating using .encode at interp-level passes?!") space = self.space s = "'\x81'" s = s.decode("koi8-u").encode("utf8") Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Tue Aug 2 12:30:13 2005 @@ -39,6 +39,7 @@ """ #from unicodecodec import * + import sys #/* --- Registry ----------------------------------------------------------- */ codec_search_path = [] @@ -216,6 +217,7 @@ def charmap_encode(obj,errors='strict',mapping='latin-1'): """None """ + res = PyUnicode_EncodeCharmap(obj,len(obj),mapping,errors) res = ''.join(res) return res, len(res) @@ -1468,9 +1470,8 @@ def charmapencode_output(c,mapping): - rep = mapping[c] - if isinstance(rep,(int,long)): + if isinstance(rep,int): if rep<256: return chr(rep) else: From rxe at codespeak.net Tue Aug 2 13:35:05 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Tue, 2 Aug 2005 13:35:05 +0200 (CEST) Subject: [pypy-svn] r15506 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050802113505.7E82027B4E@code1.codespeak.net> Author: rxe Date: Tue Aug 2 13:35:00 2005 New Revision: 15506 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/extfuncnode.py pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/node.py pypy/dist/pypy/translator/llvm2/opaquenode.py pypy/dist/pypy/translator/llvm2/structnode.py pypy/dist/pypy/translator/llvm2/test/test_seq.py Log: Airport refactors * removed prints in preference to logging * refactoring of pbc nodes after creating void array node on last day of sprint Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Tue Aug 2 13:35:00 2005 @@ -99,7 +99,6 @@ return "{ int, [%s x %s] }" % (arraylen, typeval) def get_ref(self): - """ Returns a reference as used for operations in blocks. """ typeval = self.db.repr_arg_type(lltype.typeOf(self.value)) ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), self.ref, @@ -107,15 +106,14 @@ p, c = lltype.parentlink(self.value) if p is not None: - assert False, "XXX TODO" + assert False, "XXX TODO - but needed by rtyper" return ref def get_pbcref(self, toptr): - """ Returns a reference as a pointer used per pbc. """ ref = self.ref p, c = lltype.parentlink(self.value) if p is not None: - assert False, "XXX TODO" + assert False, "XXX TODO - but needed by rtyper" fromptr = "%s*" % self.get_typerepr() refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref) @@ -129,7 +127,6 @@ index) def constantvalue(self): - """ Returns the constant representation for this node. """ arrayvalues = self.get_arrayvalues() typeval = self.db.repr_arg_type(self.arraytype) @@ -140,10 +137,18 @@ ", ".join(arrayvalues)) s = "%s {%s}" % (self.get_typerepr(), value) + return s + +class StrArrayNode(ArrayNode): + + def get_arrayvalues(self): + items = self.value.items + if len(items) == 0 or items[-1] != chr(0): + items = items + [chr(0)] + return [self.db.repr_constant(v)[1] for v in items] - #XXXX ???????? + def constantvalue(self): #XXX this does not work for arrays inlined in struct. How else to do this? - #if typeval == 'sbyte': #give more feedback for strings # limited_printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/-.' # s += ' ;"' # for item in items: @@ -152,23 +157,7 @@ # else: # s += '_' # s += '" ' - return s - - # ______________________________________________________________________ - # entry points from genllvm - - def writeglobalconstants(self, codewriter): - p, c = lltype.parentlink(self.value) - if p is None: - codewriter.globalinstance(self.ref, self.constantvalue()) - -class StrArrayNode(ArrayNode): - - def get_arrayvalues(self): - items = self.value.items - if len(items) == 0 or items[-1] != chr(0): - items = items + [chr(0)] - return [self.db.repr_constant(v)[1] for v in items] + return super(StrArrayNode, self).constantvalue() class VoidArrayNode(ConstantLLVMNode): @@ -177,23 +166,7 @@ self.ref = self.make_ref('%arrayinstance', '') self.value = value - def get_length(self): - """ returns logical length of array """ - items = self.value.items - return len(items) - - def get_typerepr(self): - return "{ int }" - - def get_arrayvalues(self): - return [] - def constantvalue(self): - value = "int %s" % (self.get_length(),) - s = "%s {%s}" % (self.get_typerepr(), value) - return s + return "{ int } {int %s}" % len(self.value.items) - def writeglobalconstants(self, codewriter): - p, c = lltype.parentlink(self.value) - if p is None: - codewriter.globalinstance(self.ref, self.constantvalue()) + Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Tue Aug 2 13:35:00 2005 @@ -11,8 +11,7 @@ from pypy.translator.tool.cbuild import make_c_from_pyxfile from pypy.translator.tool import stdoutcapture from pypy.translator.llvm2.genllvm import use_boehm_gc - -debug = True +from pypy.translator.llvm2.log import log class CompileError(exceptions.Exception): pass @@ -32,8 +31,8 @@ libraries = %(library_files)s, extra_objects = %(object_files)s)]) ''' % locals()))) - cmd = "python %s_setup.py build_ext --inplace --force" % module - if debug: print cmd + cmd ="python %s_setup.py build_ext --inplace --force" % module + log.build(cmd) cmdexec(cmd) def make_module_from_llvm(llvmfile, pyxfile, optimize=True): @@ -71,13 +70,13 @@ source_files.append("%s.c" % b) try: - if debug: print "modname", modname + log.build("modname", modname) c = stdoutcapture.Capture(mixed_out_err = True) - if debug: print "working in", path.local() + log.build("working in", path.local()) try: try: for cmd in cmds: - if debug: print cmd + log.build(cmd) cmdexec(cmd) make_c_from_pyxfile(pyxfile) compile_module(modname, source_files, object_files, library_files) @@ -88,17 +87,16 @@ fdump = open("%s.errors" % modname, "w") fdump.write(data) fdump.close() - print data + log.build(data) raise # XXX do we need to do some check on fout/ferr? # XXX not a nice way to import a module - if debug: print "inserting path to sys.path", dirpath + log.build("inserting path to sys.path", dirpath) sys.path.insert(0, '.') - if debug: print "import %(modname)s as testmodule" % locals() - exec "import %(modname)s as testmodule" % locals() + cmd = "import %(modname)s as testmodule" % locals() + log.build(cmd) + exec cmd sys.path.pop(0) finally: os.chdir(str(lastdir)) - #if not debug: - #dirpath.rmtree() return testmodule Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Tue Aug 2 13:35:00 2005 @@ -14,8 +14,6 @@ if show_line_numbers: line = "%-75s; %d" % (line, len(self._lines) + 1) self._lines.append(line) - #XXXlog(line) - print line def comment(self, line, indent=True): line = ";; " + line Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Tue Aug 2 13:35:00 2005 @@ -31,8 +31,10 @@ def __repr__(self): return repr(self._dict) def dump(self): + r = "" for x,y in self._dict.items(): - print x, y + r += "%s -> %s" % (x, y) + return r def _get(self, key): if isinstance(key, Constant): if isinstance(key.value, lltype._ptr): @@ -91,20 +93,35 @@ """ internal method for adding comments on each operation """ return self._opcomments.get(op, None) - #_______debugggin_______________________________________ + #_______debuggging______________________________________ def dump_pbcs(self): - + r = "" for k, v in self.obj2node.items(): if (isinstance(k, lltype.LowLevelType) or isinstance(k, Constant)): continue - - assert isinstance(lltype.typeOf(k), lltype.ContainerType) - print "dump_pbcs", v, "---->", k - + # XXX tmp try blocks + try: + ref = v.get_ref() + except AttributeError, e: + ref = "AttributeError: %s" % e + except AssertionError, e: + ref = "AssertionError: %s" % e + try: + pbc_ref = v.get_ref() + except AttributeError, e: + pbc_ref = "AttributeError: %s" % e + except AssertionError, e: + pbc_ref = "AssertionError: %s" % e + assert isinstance(lltype.typeOf(k), lltype.ContainerType) + r += "\ndump_pbcs %s (%s)\n" \ + "getref -> %s \n" \ + "pbcref -> %s \n" % (v, k, ref, pbc_ref) + return r + #_______create node_____________________________________ def create_constant_node(self, type_, value): Modified: pypy/dist/pypy/translator/llvm2/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/extfuncnode.py (original) +++ pypy/dist/pypy/translator/llvm2/extfuncnode.py Tue Aug 2 13:35:00 2005 @@ -24,3 +24,6 @@ def writeimpl(self, codewriter): self.used_external_functions[self.ref] = True + + def writeglobalconstants(self, codewriter): + pass Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Tue Aug 2 13:35:00 2005 @@ -89,6 +89,9 @@ typeandata = '[%s x sbyte] c"%s\\0A\\00"' % (l, strop) codewriter.globalinstance(tempname, typeandata) + def writeglobalconstants(self, codewriter): + pass + # ______________________________________________________________________ # writing helpers for entry points Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Tue Aug 2 13:35:00 2005 @@ -53,7 +53,7 @@ assert c in self.db.obj2node self.db.setup_all() - self.db.dump_pbcs() + log.compile(self.db.dump_pbcs()) self.entrynode = self.db.obj2node[c] codewriter = CodeWriter() @@ -143,7 +143,7 @@ def genllvm(translator, embedexterns=True): gen = GenLLVM(translator, embedexterns=embedexterns) - gen.compile() + log.genllvm(gen.compile()) return gen.create_module() def llvm_is_on_path(): Modified: pypy/dist/pypy/translator/llvm2/node.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/node.py (original) +++ pypy/dist/pypy/translator/llvm2/node.py Tue Aug 2 13:35:00 2005 @@ -1,3 +1,5 @@ +from pypy.rpython import lltype + class LLVMNode(object): nodename_count = {} @@ -64,7 +66,21 @@ class ConstantLLVMNode(LLVMNode): def get_ref(self): + """ Returns a reference as used for operations in blocks. """ return self.ref def get_pbcref(self, toptr): + """ Returns a reference as a pointer used per pbc. """ return self.ref + + def constantvalue(self): + """ Returns the constant representation for this node. """ + raise AttributeError("Must be implemented in subclass") + + # ______________________________________________________________________ + # entry points from genllvm + + def writeglobalconstants(self, codewriter): + p, c = lltype.parentlink(self.value) + if p is None: + codewriter.globalinstance(self.ref, self.constantvalue()) Modified: pypy/dist/pypy/translator/llvm2/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opaquenode.py (original) +++ pypy/dist/pypy/translator/llvm2/opaquenode.py Tue Aug 2 13:35:00 2005 @@ -25,3 +25,9 @@ self.db = db self.value = value self.ref = "null" + # ______________________________________________________________________ + # main entry points from genllvm + + def writeglobalconstants(self, codewriter): + # XXX Dummy - not sure what what we want + pass Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Tue Aug 2 13:35:00 2005 @@ -145,13 +145,6 @@ all_values = ",\n ".join(values) return "%s {\n %s\n }\n" % (self.get_typerepr(), all_values) - # ______________________________________________________________________ - # main entry points from genllvm - - def writeglobalconstants(self, codewriter): - p, c = lltype.parentlink(self.value) - if p is None: - codewriter.globalinstance(self.ref, self.constantvalue()) class StructVarsizeNode(StructNode): """ A varsize struct constant. Can simply contain Modified: pypy/dist/pypy/translator/llvm2/test/test_seq.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_seq.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_seq.py Tue Aug 2 13:35:00 2005 @@ -18,7 +18,6 @@ def test_array_setitem(self): f = compile_function(llvmsnippet.array_setitem, [int]) - print f(1), f(2), f(3) assert f(1) == 12 assert f(2) == 13 assert f(3) == 3 From ericvrp at codespeak.net Tue Aug 2 15:02:06 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 2 Aug 2005 15:02:06 +0200 (CEST) Subject: [pypy-svn] r15508 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050802130206.BF3DD27B4D@code1.codespeak.net> Author: ericvrp Date: Tue Aug 2 15:02:05 2005 New Revision: 15508 Modified: pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: - enabled more passing tests - finally use correct type for exc_type and exc_value globals - remove call to issubclass for "except: cases Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Tue Aug 2 15:02:05 2005 @@ -133,6 +133,9 @@ def write_block_branches(self, codewriter, block): #assert len(block.exits) <= 2 #more exits are possible (esp. in combination with exceptions) + if block.exitswitch == Constant(last_exception): + #codewriter.comment('FuncNode(ConstantLLVMNode) *last_exception* write_block_branches @%s@' % str(block.exits)) + return if len(block.exits) == 1: codewriter.br_uncond(self.block_to_name[block.exits[0].target]) elif len(block.exits) == 2: @@ -201,13 +204,8 @@ inputargs = self.db.repr_arg_multi(block.inputargs) inputargtypes = self.db.repr_arg_type_multi(block.inputargs) - tmptype, tmpvar = 'sbyte*', self.db.repr_tmpvar() - codewriter.cast(tmpvar, inputargtypes[0], inputargs[0], tmptype) - codewriter.store(tmptype, tmpvar, '%last_exception_type') - - tmptype, tmpvar = 'sbyte*', self.db.repr_tmpvar() - codewriter.cast(tmpvar, inputargtypes[1], inputargs[1], tmptype) - codewriter.store(tmptype, tmpvar, '%last_exception_value') + codewriter.store(inputargtypes[0], inputargs[0], '%last_exception_type') + codewriter.store(inputargtypes[1], inputargs[1], '%last_exception_value') else: codewriter.comment('reraise last exception') #Reraising last_exception. Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Tue Aug 2 15:02:05 2005 @@ -6,10 +6,8 @@ %structtype.rpy_string = type {int, {int, [0 x sbyte]}} ;exception handling globals -%last_exception_type = global sbyte* null -%last_exception_value = global sbyte* null -;%last_exception_type = global %structtype.object_vtable* null -;%last_exception_value = global %structtype.object* null +%last_exception_type = global %structtype.object_vtable* null +%last_exception_value = global %structtype.object* null """ gc_boehm = """declare sbyte* %GC_malloc(uint) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Tue Aug 2 15:02:05 2005 @@ -262,19 +262,15 @@ e.lltype_of_exception_type.TO.__name__ + '*') - tmptype1, tmpvar1 = 'sbyte*', self.db.repr_tmpvar() - tmptype2, tmpvar2 = lltype_of_exception_type, self.db.repr_tmpvar() - self.codewriter.label(exc_label) - self.codewriter.load(tmpvar1, tmptype1, '%last_exception_type') - self.codewriter.cast(tmpvar2, tmptype1, tmpvar1, tmptype2) - self.codewriter.newline() - exc_found_labels = [] + exc_found_labels, last_exception_type = [], None for link in self.block.exits[1:]: assert issubclass(link.exitcase, Exception) etype = self.db.obj2node[link.llexitcase._obj] + current_exception_type = etype.get_ref() + #self.codewriter.comment('etype=%s, current_exception_type=%s' % (str(etype.ref), str(current_exception_type))) target = self.node.block_to_name[link.target] exc_found_label = block_label + '_exception_found_branchto_' + target @@ -282,18 +278,26 @@ not_this_exception_label = block_label + '_not_exception_' + etype.ref[1:] - ll_issubclass_cond = self.db.repr_tmpvar() - self.codewriter.call(ll_issubclass_cond, - 'bool', - ll_exception_match, - [etype.get_ref(), tmpvar2], - [lltype_of_exception_type, lltype_of_exception_type]) - self.codewriter.br(ll_issubclass_cond, not_this_exception_label, exc_found_label) + if current_exception_type.find('getelementptr') == -1: #XXX catch all (except:) + self.codewriter.br_uncond(exc_found_label) + else: + if not last_exception_type: + last_exception_type = self.db.repr_tmpvar() + self.codewriter.load(last_exception_type, lltype_of_exception_type, '%last_exception_type') + #self.codewriter.newline() + ll_issubclass_cond = self.db.repr_tmpvar() + self.codewriter.call(ll_issubclass_cond, + 'bool', + ll_exception_match, + [last_exception_type, current_exception_type], + [lltype_of_exception_type, lltype_of_exception_type]) + self.codewriter.br(ll_issubclass_cond, not_this_exception_label, exc_found_label) + self.codewriter.label(not_this_exception_label) - self.codewriter.comment('this code should never be reached!') + self.codewriter.comment('reraise when exception is not caught') self.codewriter.unwind() - #self.codewriter.br_uncond(none_label) + for label, target in exc_found_labels: self.codewriter.label(label) self.codewriter.br_uncond(target) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Tue Aug 2 15:02:05 2005 @@ -11,6 +11,8 @@ self.n = n def getitem(l, i): #LookupError, KeyError + if not isinstance(i, int): + raise LookupError if i < 0: i = len(l) - i if i>= len(l): @@ -18,7 +20,6 @@ return l[i] def test_simple1(): - #py.test.skip("not working yet") def raise_(i): if i: raise TestException() @@ -37,8 +38,6 @@ assert f(1) == fn(1) def test_simple2(): - #py.test.skip("not working yet, lst[n] raises no exceptions") - py.test.skip('failing') def fn(n): lst = range(10) try: @@ -52,7 +51,6 @@ assert f(10) == fn(10) def test_simple3(): - #py.test.skip("not working yet") def raise_(i): if i == 0: raise TestException() @@ -79,8 +77,6 @@ assert f(2) == fn(2) def test_pass_exc(): - #py.test.skip("not working yet, lst[n] raises no exceptions") - py.test.skip('failing') def fn(n): lst = range(10) try: @@ -93,20 +89,19 @@ assert f( 0) == fn( 0) assert f(10) == fn(10) -def test_divzero(): - py.test.skip("not working yet") - def fn(n): - try: - n/0 - except: - return 2 - return 4 - f = compile_function(fn, [int]) - assert f(0) == fn(0) +#def test_divzero(): +# py.test.skip("divzero not working yet") +# def fn(n): +# try: +# n/0 +# except: +# return 2 +# return 4 +# f = compile_function(fn, [int]) +# assert f(0) == fn(0) def test_reraise1(): - #py.test.skip("not working yet, lst[n] raises no exceptions") - py.test.skip('failing') + py.test.skip("failing") #uncaught exception causes exit! def fn(n): lst = range(10) try: @@ -120,8 +115,7 @@ assert f(10) == fn(10) def test_reraise2(): - #py.test.skip("not working yet, lst[n] raises no exceptions") - py.test.skip('failing') + py.test.skip("failing") #uncaught exception causes exit! def fn(n): lst = range(10) try: @@ -135,7 +129,6 @@ assert f(10) == fn(10) def test_simple_exception(): - #py.test.skip("not working yet, lst[n] raises no exceptions") def fn(n): lst = range(10) try: @@ -150,8 +143,7 @@ assert f(i) == fn(i) def test_two_exceptions(): - #py.test.skip("not working yet, lst[n] raises no exceptions") - py.test.skip('failing') + py.test.skip("failing") def fn(n): lst = range(10) try: @@ -168,8 +160,6 @@ assert f(i) == fn(i) def test_catch_base_exception(): - py.test.skip('aborted') - #py.test.skip("not working yet, lst[n] raises no exceptions") def fn(n): lst = range(10) try: @@ -183,9 +173,8 @@ for i in range(10, 20): assert f(i) == fn(i) - def test_catches(): - py.test.skip("not working yet") + py.test.skip("failing") #"except: exception, value" not implemented yet def raises(i): if i == 3: raise MyException, 12 @@ -209,7 +198,6 @@ assert f(13) == fn(13) def test_try_raise_choose(): - py.test.skip("not working yet") f = compile_function(try_raise_choose, [int]) for i in [-1, 0, 1, 2]: assert f(i) == i From pedronis at codespeak.net Tue Aug 2 15:56:48 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 2 Aug 2005 15:56:48 +0200 (CEST) Subject: [pypy-svn] r15509 - pypy/extradoc/sprintinfo Message-ID: <20050802135648.374A427B4D@code1.codespeak.net> Author: pedronis Date: Tue Aug 2 15:56:46 2005 New Revision: 15509 Modified: pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt Log: first pass at filing issues described here (up to cleanups). Divided sections for cleanups vs. other more precise issues. Modified: pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt ============================================================================== --- pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt (original) +++ pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt Tue Aug 2 15:56:46 2005 @@ -1,6 +1,7 @@ planning for the time between the Hildesheim and Heidelberg sprints =================================================================== + clean-up areas -------------- @@ -10,38 +11,44 @@ - initialization of the object space is still messy -- rtyper problem: exceptions are no longer always at the end of a code - block because of the lowlevel rewriting - -- translation problem: frozen ids used as hashes are broken - in the post-translation program - - move bits around in the annotator to make different uses more pluggable -- better support of math and float exceptions - - reorganizing some wrongly named things - erasing useless files - cleanup of import dependencies -- support for tests from external users and different platforms - - preparing the next release +- look into XXX issues + + +filed as issues +------------- + +- rtyper problem: exceptions are no longer always at the end of a code + block because of the lowlevel rewriting + +- translation problem: frozen ids used as hashes are broken + in the post-translation program + +- better support of math and float exceptions + - documentation about external function calls and implementing builtin modules +- prefixing all the C macros and names with pypy + +- support producing a windows binary, choose a suitable compiler + + - related to the previous: documenting how interplevel marshal is plugged into the system -- prefixing all the C macros and names with pypy - -- look into XXX issues +- support for tests from external users and different platforms -- support producing a windows binary, choose a suitable compiler other issues --------------------- From ericvrp at codespeak.net Tue Aug 2 16:17:48 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 2 Aug 2005 16:17:48 +0200 (CEST) Subject: [pypy-svn] r15510 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050802141748.84E8427B4D@code1.codespeak.net> Author: ericvrp Date: Tue Aug 2 16:17:47 2005 New Revision: 15510 Modified: pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: Almost all exceptions tests now pass. One, possible PBC related, test is failing. Two tests are failing because an exception in the llvm code is currently not converted to a CPython exception. The imported (pyrex) module for some reason then exits but I am not sure if I want the put any effort into fixing this (at the moment). Especially since the purpose is to have a selfreliant 'llvm-executable'. Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Tue Aug 2 16:17:47 2005 @@ -129,7 +129,12 @@ link.prevblock.exits[0].target != block: blocknames[i] += '_exception_found_branchto_' + self.block_to_name[block] if type_ != "void": - codewriter.phi(arg, type_, names, blocknames) + if arg.startswith('%last_exc_value_') and type_ == '%structtype.object*': + e = self.db._translator.rtyper.getexceptiondata() + lltype_of_exception_value = ('%structtype.' + e.lltype_of_exception_value.TO.__name__ + '*') + codewriter.load(arg, lltype_of_exception_value, '%last_exception_value') + else: + codewriter.phi(arg, type_, names, blocknames) def write_block_branches(self, codewriter, block): #assert len(block.exits) <= 2 #more exits are possible (esp. in combination with exceptions) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Tue Aug 2 16:17:47 2005 @@ -284,7 +284,7 @@ if not last_exception_type: last_exception_type = self.db.repr_tmpvar() self.codewriter.load(last_exception_type, lltype_of_exception_type, '%last_exception_type') - #self.codewriter.newline() + self.codewriter.newline() ll_issubclass_cond = self.db.repr_tmpvar() self.codewriter.call(ll_issubclass_cond, 'bool', Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Tue Aug 2 16:17:47 2005 @@ -33,6 +33,8 @@ return a+b+c except TestException: return 7 + else: + return 3 f = compile_function(fn, [int]) assert f(0) == fn(0) assert f(1) == fn(1) @@ -101,7 +103,7 @@ # assert f(0) == fn(0) def test_reraise1(): - py.test.skip("failing") #uncaught exception causes exit! + py.test.skip("failing, uncaught exception causes exit!") def fn(n): lst = range(10) try: @@ -115,7 +117,7 @@ assert f(10) == fn(10) def test_reraise2(): - py.test.skip("failing") #uncaught exception causes exit! + py.test.skip("failing, uncaught exception causes exit!") def fn(n): lst = range(10) try: @@ -143,7 +145,7 @@ assert f(i) == fn(i) def test_two_exceptions(): - py.test.skip("failing") + py.test.skip("failing, PBC problem?") def fn(n): lst = range(10) try: @@ -174,7 +176,6 @@ assert f(i) == fn(i) def test_catches(): - py.test.skip("failing") #"except: exception, value" not implemented yet def raises(i): if i == 3: raise MyException, 12 @@ -188,11 +189,13 @@ return raises(i) except MyException, e: return e.n + except: + return 123 f = compile_function(fn, [int]) assert f(1) == fn(1) assert f(2) == fn(2) assert f(3) == fn(3) - py.test.raises(RuntimeError, "f(4)") + #py.test.raises(RuntimeError, "f(4)") #currently not raising a CPython exception assert f(5) == fn(5) assert f(6) == fn(6) assert f(13) == fn(13) From arigo at codespeak.net Tue Aug 2 16:55:05 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 2 Aug 2005 16:55:05 +0200 (CEST) Subject: [pypy-svn] r15511 - in pypy/dist/pypy/translator: . c c/test tool Message-ID: <20050802145505.68FB627B4E@code1.codespeak.net> Author: arigo Date: Tue Aug 2 16:55:04 2005 New Revision: 15511 Added: pypy/dist/pypy/translator/c/test/test_standalone.py - copied, changed from r15510, pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py Removed: pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/tool/cbuild.py pypy/dist/pypy/translator/translator.py Log: Finished the CBuilder class, now split in two subclasses as per Holger's suggestion -- one for building C extension modules and one for standalone executables. The test pass, at least on Linux. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Aug 2 16:55:04 2005 @@ -5,29 +5,24 @@ from pypy.translator.c.extfunc import pre_include_code_lines from pypy.translator.gensupp import uniquemodulename from pypy.translator.tool.cbuild import compile_c_module +from pypy.translator.tool.cbuild import build_executable from pypy.translator.tool.cbuild import import_module_from_directory from pypy.rpython.rmodel import getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir class CBuilder: - def __init__(self, translator, standalone=False): + c_source_filename = None + _compiled = False + symboltable = None + + def __init__(self, translator): self.translator = translator - self.standalone = standalone - self.c_source_filename = None - self._compiled = False - self.c_ext_module = None def generate_source(self): assert self.c_source_filename is None translator = self.translator - entrypoint = translator.entrypoint - if not self.standalone: - pf = lltype.pyobjectptr(entrypoint) - else: - # XXX check that the entrypoint has the correct - # signature: list-of-strings -> int - pf = getfunctionptr(translator, entrypoint) + pf = self.getentrypointptr() db = LowLevelDatabase(translator, standalone=self.standalone) pfname = db.get(pf) db.complete() @@ -44,16 +39,22 @@ exports = {translator.entrypoint.func_name: pf}, symboltable = self.symboltable) else: - self.symboltable = None cfile = gen_source_standalone(db, modulename, targetdir, entrypointname = pfname, defines = defines) self.c_source_filename = py.path.local(cfile) return cfile - + + +class CExtModuleBuilder(CBuilder): + standalone = False + + def getentrypointptr(self): + return lltype.pyobjectptr(self.translator.entrypoint) + def compile(self): assert self.c_source_filename - assert not self.standalone, "XXX" + assert not self._compiled compile_c_module(self.c_source_filename, self.c_source_filename.purebasename, include_dirs = [autopath.this_dir]) @@ -74,6 +75,29 @@ return getattr(self.c_ext_module, self.translator.entrypoint.func_name) + +class CStandaloneBuilder(CBuilder): + standalone = True + executable_name = None + + def getentrypointptr(self): + # XXX check that the entrypoint has the correct + # signature: list-of-strings -> int + return getfunctionptr(self.translator, self.translator.entrypoint) + + def compile(self): + assert self.c_source_filename + assert not self._compiled + self.executable_name = build_executable([self.c_source_filename], + include_dirs = [autopath.this_dir]) + self._compiled = True + return self.executable_name + + def cmdexec(self, args=''): + assert self._compiled + return py.process.cmdexec('"%s" %s' % (self.executable_name, args)) + + def translator2database(translator): pf = pyobjectptr(translator.entrypoint) db = LowLevelDatabase(translator) Deleted: /pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py ============================================================================== --- /pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py Tue Aug 2 16:55:04 2005 +++ (empty file) @@ -1,23 +0,0 @@ -from pypy.translator.translator import Translator -from pypy.translator.tool.cbuild import build_executable -from pypy.annotation.model import SomeList, SomeString -from pypy.annotation.listdef import ListDef -import os - - -def test_hello_world(): - def entry_point(argv): - os.write(1, "hello world\n") - os.write(1, "argument count: " + str(len(argv)) + "\n") - for s in argv: - os.write(1, " '" + str(s) + "'\n") - return 0 - - t = Translator(entry_point) - s_list_of_strings = SomeList(ListDef(None, SomeString())) - t.annotate([s_list_of_strings]) - t.specialize() - cbuilder = t.cbuilder(standalone=True) - cbuilder.generate_source() - cbuilder.compile() - XXX Copied: pypy/dist/pypy/translator/c/test/test_standalone.py (from r15510, pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py) ============================================================================== --- pypy/dist/pypy/translator/c/test/inprogress_test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Aug 2 16:55:04 2005 @@ -8,6 +8,7 @@ def test_hello_world(): def entry_point(argv): os.write(1, "hello world\n") + argv = argv[1:] os.write(1, "argument count: " + str(len(argv)) + "\n") for s in argv: os.write(1, " '" + str(s) + "'\n") @@ -20,4 +21,5 @@ cbuilder = t.cbuilder(standalone=True) cbuilder.generate_source() cbuilder.compile() - XXX + data = cbuilder.cmdexec('hi there') + assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Tue Aug 2 16:55:04 2005 @@ -226,7 +226,8 @@ return getattr(mod, func.func_name) -def build_executable(cfilenames, outputfilename=None, include_dirs=None): +def build_executable(cfilenames, outputfilename=None, include_dirs=None, + libraries=['m']): from distutils.ccompiler import new_compiler if outputfilename is None: if sys.platform == 'win32': @@ -251,6 +252,7 @@ objects.append(str(cobjfile)) finally: old.chdir() - compiler.link_executable(objects, str(outputfilename)) + compiler.link_executable(objects, str(outputfilename), + libraries=libraries) return str(outputfilename) Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Tue Aug 2 16:55:04 2005 @@ -268,7 +268,10 @@ def cbuilder(self, standalone=False): from pypy.translator.c import genc - return genc.CBuilder(self, standalone=standalone) + if standalone: + return genc.CStandaloneBuilder(self) + else: + return genc.CExtModuleBuilder(self) def llvmcompile(self, optimize=True): """llvmcompile(self, optimize=True) -> LLVM translation From rxe at codespeak.net Tue Aug 2 17:12:58 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Tue, 2 Aug 2005 17:12:58 +0200 (CEST) Subject: [pypy-svn] r15512 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050802151258.F33A427B4E@code1.codespeak.net> Author: rxe Date: Tue Aug 2 17:12:57 2005 New Revision: 15512 Modified: pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: Setup pbcs in block exits when we exitcase as last_exception. Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Tue Aug 2 17:12:57 2005 @@ -46,10 +46,17 @@ if isinstance(node, Link): map(self.db.prepare_arg, node.args) elif isinstance(node, Block): - map(self.db.prepare_arg, node.inputargs) - for op in node.operations: + block = node + map(self.db.prepare_arg, block.inputargs) + for op in block.operations: map(self.db.prepare_arg, op.args) self.db.prepare_arg(op.result) + if block.exitswitch != Constant(last_exception): + continue + for link in block.exits[1:]: + self.db.prepare_constant(lltype.typeOf(link.llexitcase), + link.llexitcase) + assert self.graph, "cannot traverse" traverse(visit, self.graph) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Tue Aug 2 17:12:57 2005 @@ -145,7 +145,6 @@ assert f(i) == fn(i) def test_two_exceptions(): - py.test.skip("failing, PBC problem?") def fn(n): lst = range(10) try: From hpk at codespeak.net Tue Aug 2 20:32:05 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 2 Aug 2005 20:32:05 +0200 (CEST) Subject: [pypy-svn] r15520 - pypy/dist/pypy/translator/c Message-ID: <20050802183205.C404A27B4D@code1.codespeak.net> Author: hpk Date: Tue Aug 2 20:32:03 2005 New Revision: 15520 Modified: pypy/dist/pypy/translator/c/genc.py Log: fix bug for c-ext modules (used by current translator targetpypymain.py goal) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Aug 2 20:32:03 2005 @@ -48,6 +48,7 @@ class CExtModuleBuilder(CBuilder): standalone = False + c_ext_module = None def getentrypointptr(self): return lltype.pyobjectptr(self.translator.entrypoint) From nik at codespeak.net Tue Aug 2 20:34:52 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 2 Aug 2005 20:34:52 +0200 (CEST) Subject: [pypy-svn] r15521 - in pypy/dist: lib-python lib-python/modified-2.4.1 lib-python/modified-2.4.1/test pypy/interpreter pypy/module/_sre Message-ID: <20050802183452.0E0A827B4E@code1.codespeak.net> Author: nik Date: Tue Aug 2 20:34:47 2005 New Revision: 15521 Added: pypy/dist/lib-python/modified-2.4.1/test/test_re.py - copied, changed from r15502, pypy/dist/lib-python/2.4.1/test/test_re.py pypy/dist/pypy/module/_sre/ pypy/dist/pypy/module/_sre/__init__.py (contents, props changed) pypy/dist/pypy/module/_sre/app_sre.py (contents, props changed) Modified: pypy/dist/lib-python/conftest.py pypy/dist/lib-python/modified-2.4.1/sre_constants.py pypy/dist/pypy/interpreter/baseobjspace.py Log: integrated my pure applevel _sre module. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Aug 2 20:34:47 2005 @@ -611,8 +611,7 @@ #gen = random.WichmannHill() #AttributeError: 'module' object has no attribute 'WichmannHill' - RegrTest('test_re.py', enabled=False), - #rev 10840: 7 of 47 tests fail + RegrTest('test_re.py', enabled=True), RegrTest('test_regex.py', enabled=False), RegrTest('test_repr.py', enabled=False, core="ill-defined"), Modified: pypy/dist/lib-python/modified-2.4.1/sre_constants.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/sre_constants.py (original) +++ pypy/dist/lib-python/modified-2.4.1/sre_constants.py Tue Aug 2 20:34:47 2005 @@ -129,11 +129,13 @@ # PyPy hack to make the sre_*.py files from 2.4.1 work on the _sre # engine of 2.3. -import _sre -if _sre.MAGIC < 20031017: - OPCODES.remove(GROUPREF_EXISTS) -del _sre - +# XXX This hack doesn't work anymore because it creates a circular import +# problem. Maybe think about a different hack, otherwise we're not able to run +# faked _sre on CPython 2.3. +#import _sre +#if _sre.MAGIC < 20031017: +# OPCODES.remove(GROUPREF_EXISTS) +#del _sre ATCODES = [ AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY, Copied: pypy/dist/lib-python/modified-2.4.1/test/test_re.py (from r15502, pypy/dist/lib-python/2.4.1/test/test_re.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_re.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_re.py Tue Aug 2 20:34:47 2005 @@ -4,8 +4,8 @@ from test.test_support import verbose, run_unittest import re from sre import Scanner -import sys, os, traceback -from weakref import proxy +import sys, os #, traceback +#from weakref import proxy # Misc tests from Tim Peters' re.doc @@ -17,7 +17,8 @@ class ReTests(unittest.TestCase): - def test_weakref(self): + def DONOTtest_weakref(self): + # XXX disabled until PyPy supports weakrefs s = 'QabbbcR' x = re.compile('ab+c') y = proxy(x) @@ -406,7 +407,11 @@ oldpat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)') s = pickle.dumps(oldpat) newpat = pickle.loads(s) - self.assertEqual(oldpat, newpat) + # Not using object identity for _sre.py, since some Python builds do + # not seem to preserve that in all cases (observed on an UCS-4 build + # of 2.4.1). + #self.assertEqual(oldpat, newpat) + self.assertEqual(oldpat.__dict__, newpat.__dict__) def test_constants(self): self.assertEqual(re.I, re.IGNORECASE) @@ -457,7 +462,9 @@ # should, instead provoking a TypeError. self.assertRaises(re.error, re.compile, 'foo[a-') - def test_bug_418626(self): + def DONOTtest_bug_418626(self): + # XXX disabled for PyPy, too time-consuming. But our implementation is + # in fact non-recursive as well. # bugs 418626 at al. -- Testing Greg Chapman's addition of op code # SRE_OP_MIN_REPEAT_ONE for eliminating recursion on simple uses of # pattern '*?' on a long string. @@ -473,7 +480,9 @@ pat=u"["+re.escape(u"\u2039")+u"]" self.assertEqual(re.compile(pat) and 1, 1) - def test_stack_overflow(self): + def DONOTtest_stack_overflow(self): + # XXX disabled for PyPy, too time-consuming. But our implementation is + # in fact non-recursive as well. # nasty cases that used to overflow the straightforward recursive # implementation of repeated groups. self.assertEqual(re.match('(x)*', 50000*'x').group(1), 'x') @@ -611,8 +620,9 @@ except KeyboardInterrupt: raise KeyboardInterrupt except: print '*** Unexpected error ***', t - if verbose: - traceback.print_exc(file=sys.stdout) + # Traceback disabled in PyPy for speed reasons + #if verbose: + # traceback.print_exc(file=sys.stdout) else: try: result = obj.search(s) @@ -709,7 +719,9 @@ def test_main(): run_unittest(ReTests) - run_re_tests() + # XXX Disabled re_tests for PyPy because they take approximately forever + # to run ... + #run_re_tests() if __name__ == "__main__": test_main() Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Tue Aug 2 20:34:47 2005 @@ -160,7 +160,8 @@ except AttributeError: pass - l = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs'] + l = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', + '_sre'] if self.options.nofaking: l.append('posix') Added: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/__init__.py Tue Aug 2 20:34:47 2005 @@ -0,0 +1,17 @@ +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + + appleveldefs = { + '__name__': 'app_sre.__name__', + '__doc__': 'app_sre.__doc__', + 'CODESIZE': 'app_sre.CODESIZE', + 'MAGIC': 'app_sre.CODESIZE', + 'copyright': 'app_sre.copyright', + 'compile': 'app_sre.compile', + 'getcodesize': 'app_sre.getcodesize', + 'getlower': 'app_sre.getlower', + } + + interpleveldefs = { + } Added: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/app_sre.py Tue Aug 2 20:34:47 2005 @@ -0,0 +1,1192 @@ +# NOT_RPYTHON +""" +A pure Python reimplementation of the _sre module from CPython 2.4 +Copyright 2005 Nik Haldimann, licensed under the MIT license + +This code is based on material licensed under CNRI's Python 1.6 license and +copyrighted by: Copyright (c) 1997-2001 by Secret Labs AB +""" + +import array, operator, sys +import sre_constants +from sre_constants import ATCODES, OPCODES, CHCODES, MAXREPEAT + +# Identifying as _sre from Python 2.3 or 2.4 +if sys.version_info[:2] == (2, 4): + MAGIC = 20031017 +else: + MAGIC = 20030419 + +# In _sre.c this is bytesize of the code word type of the C implementation. +# There it's 2 for normal Python builds and more for wide unicode builds (large +# enough to hold a 32-bit UCS-4 encoded character). Since here in pure Python +# we only see re bytecodes as Python longs, we shouldn't have to care about the +# codesize. But sre_compile will compile some stuff differently depending on the +# codesize (e.g., charsets). +if sys.maxunicode == 65535: + CODESIZE = 2 +else: + CODESIZE = 4 + +copyright = "_sre.py 2.4a Copyright 2005 by Nik Haldimann" + + +def getcodesize(): + return CODESIZE + +def compile(pattern, flags, code, groups=0, groupindex={}, indexgroup=[None]): + """Compiles (or rather just converts) a pattern descriptor to a SRE_Pattern + object. Actual compilation to opcodes happens in sre_compile.""" + return SRE_Pattern(pattern, flags, code, groups, groupindex, indexgroup) + +def getlower(char_ord, flags): + if (char_ord < 128) or (flags & sre_constants.SRE_FLAG_UNICODE) \ + or (flags & sre_constants.SRE_FLAG_LOCALE and char_ord < 256): + return ord(unichr(char_ord).lower()) + else: + return char_ord + + +class SRE_Pattern(object): + + def __init__(self, pattern, flags, code, groups=0, groupindex={}, indexgroup=[None]): + self.pattern = pattern + self.flags = flags + self.groups = groups + self.groupindex = groupindex # Maps group names to group indices + self._indexgroup = indexgroup # Maps indices to group names + self._code = code + + def match(self, string, pos=0, endpos=sys.maxint): + """If zero or more characters at the beginning of string match this + regular expression, return a corresponding MatchObject instance. Return + None if the string does not match the pattern.""" + state = _State(string, pos, endpos, self.flags) + if state.match(self._code): + return SRE_Match(self, state) + else: + return None + + def search(self, string, pos=0, endpos=sys.maxint): + """Scan through string looking for a location where this regular + expression produces a match, and return a corresponding MatchObject + instance. Return None if no position in the string matches the + pattern.""" + state = _State(string, pos, endpos, self.flags) + if state.search(self._code): + return SRE_Match(self, state) + else: + return None + + def findall(self, string, pos=0, endpos=sys.maxint): + """Return a list of all non-overlapping matches of pattern in string.""" + matchlist = [] + state = _State(string, pos, endpos, self.flags) + while state.start <= state.end: + state.reset() + state.string_position = state.start + if not state.search(self._code): + break + match = SRE_Match(self, state) + if self.groups == 0 or self.groups == 1: + item = match.group(self.groups) + else: + item = match.groups("") + matchlist.append(item) + if state.string_position == state.start: + state.start += 1 + else: + state.start = state.string_position + return matchlist + + def _subx(self, template, string, count=0, subn=False): + filter = template + if not callable(template) and "\\" in template: + # handle non-literal strings ; hand it over to the template compiler + import sre + filter = sre._subx(self, template) + state = _State(string, 0, sys.maxint, self.flags) + sublist = [] + + n = last_pos = 0 + while not count or n < count: + state.reset() + state.string_position = state.start + if not state.search(self._code): + break + if last_pos < state.start: + sublist.append(string[last_pos:state.start]) + if not (last_pos == state.start and + last_pos == state.string_position and n > 0): + # the above ignores empty matches on latest position + if callable(filter): + sublist.append(filter(SRE_Match(self, state))) + else: + sublist.append(filter) + last_pos = state.string_position + n += 1 + if state.string_position == state.start: + state.start += 1 + else: + state.start = state.string_position + + if last_pos < state.end: + sublist.append(string[last_pos:state.end]) + item = "".join(sublist) + if subn: + return item, n + else: + return item + + def sub(self, repl, string, count=0): + """Return the string obtained by replacing the leftmost non-overlapping + occurrences of pattern in string by the replacement repl.""" + return self._subx(repl, string, count, False) + + def subn(self, repl, string, count=0): + """Return the tuple (new_string, number_of_subs_made) found by replacing + the leftmost non-overlapping occurrences of pattern with the replacement + repl.""" + return self._subx(repl, string, count, True) + + def split(self, string, maxsplit=0): + """Split string by the occurrences of pattern.""" + splitlist = [] + state = _State(string, 0, sys.maxint, self.flags) + n = 0 + last = state.start + while not maxsplit or n < maxsplit: + state.reset() + state.string_position = state.start + if not state.search(self._code): + break + if state.start == state.string_position: # zero-width match + if last == state.end: # or end of string + break + state.start += 1 + continue + splitlist.append(string[last:state.start]) + # add groups (if any) + if self.groups: + match = SRE_Match(self, state) + splitlist.extend(list(match.groups(None))) + n += 1 + last = state.start = state.string_position + splitlist.append(string[last:state.end]) + return splitlist + + def finditer(self, string, pos=0, endpos=sys.maxint): + """Return a list of all non-overlapping matches of pattern in string.""" + scanner = self.scanner(string, pos, endpos) + return iter(scanner.search, None) + + def scanner(self, string, start=0, end=sys.maxint): + return SRE_Scanner(self, string, start, end) + + def __copy__(self): + raise TypeError, "cannot copy this pattern object" + + def __deepcopy__(self): + raise TypeError, "cannot copy this pattern object" + + +class SRE_Scanner(object): + """Undocumented scanner interface of sre.""" + + def __init__(self, pattern, string, start, end): + self.pattern = pattern + self._state = _State(string, start, end, self.pattern.flags) + + def _match_search(self, matcher): + state = self._state + state.reset() + state.string_position = state.start + match = None + if matcher(self.pattern._code): + match = SRE_Match(self.pattern, state) + if match is None or state.string_position == state.start: + state.start += 1 + else: + state.start = state.string_position + return match + + def match(self): + return self._match_search(self._state.match) + + def search(self): + return self._match_search(self._state.search) + + +class SRE_Match(object): + + def __init__(self, pattern, state): + self.re = pattern + self.string = state.string + self.pos = state.pos + self.endpos = state.end + self.lastindex = state.lastindex + if self.lastindex < 0: + self.lastindex = None + self.regs = self._create_regs(state) + if pattern._indexgroup and 0 <= self.lastindex < len(pattern._indexgroup): + # The above upper-bound check should not be necessary, as the re + # compiler is supposed to always provide an _indexgroup list long + # enough. But the re.Scanner class seems to screw up something + # there, test_scanner in test_re won't work without upper-bound + # checking. XXX investigate this and report bug to CPython. + self.lastgroup = pattern._indexgroup[self.lastindex] + else: + self.lastgroup = None + + def _create_regs(self, state): + """Creates a tuple of index pairs representing matched groups.""" + regs = [(state.start, state.string_position)] + for group in range(self.re.groups): + mark_index = 2 * group + if mark_index + 1 < len(state.marks) \ + and state.marks[mark_index] is not None \ + and state.marks[mark_index + 1] is not None: + regs.append((state.marks[mark_index], state.marks[mark_index + 1])) + else: + regs.append((-1, -1)) + return tuple(regs) + + def _get_index(self, group): + if isinstance(group, int): + if group >= 0 and group <= self.re.groups: + return group + else: + if self.re.groupindex.has_key(group): + return self.re.groupindex[group] + raise IndexError("no such group") + + def _get_slice(self, group, default): + group_indices = self.regs[group] + if group_indices[0] >= 0: + return self.string[group_indices[0]:group_indices[1]] + else: + return default + + def start(self, group=0): + """Returns the indices of the start of the substring matched by group; + group defaults to zero (meaning the whole matched substring). Returns -1 + if group exists but did not contribute to the match.""" + return self.regs[self._get_index(group)][0] + + def end(self, group=0): + """Returns the indices of the end of the substring matched by group; + group defaults to zero (meaning the whole matched substring). Returns -1 + if group exists but did not contribute to the match.""" + return self.regs[self._get_index(group)][1] + + def span(self, group=0): + """Returns the 2-tuple (m.start(group), m.end(group)).""" + return self.start(group), self.end(group) + + def expand(self, template): + """Return the string obtained by doing backslash substitution and + resolving group references on template.""" + import sre + return sre._expand(self.re, self, template) + + def groups(self, default=None): + """Returns a tuple containing all the subgroups of the match. The + default argument is used for groups that did not participate in the + match (defaults to None).""" + groups = [] + for indices in self.regs[1:]: + if indices[0] >= 0: + groups.append(self.string[indices[0]:indices[1]]) + else: + groups.append(default) + return tuple(groups) + + def groupdict(self, default=None): + """Return a dictionary containing all the named subgroups of the match. + The default argument is used for groups that did not participate in the + match (defaults to None).""" + groupdict = {} + for key, value in self.re.groupindex.items(): + groupdict[key] = self._get_slice(value, default) + return groupdict + + def group(self, *args): + """Returns one or more subgroups of the match. Each argument is either a + group index or a group name.""" + if len(args) == 0: + args = (0,) + grouplist = [] + for group in args: + grouplist.append(self._get_slice(self._get_index(group), None)) + if len(grouplist) == 1: + return grouplist[0] + else: + return tuple(grouplist) + + def __copy__(): + raise TypeError, "cannot copy this pattern object" + + def __deepcopy__(): + raise TypeError, "cannot copy this pattern object" + + +class _State(object): + + def __init__(self, string, start, end, flags): + self.string = string + if start < 0: + start = 0 + if end > len(string): + end = len(string) + self.start = start + self.string_position = self.start + self.end = end + self.pos = start + self.flags = flags + self.reset() + + def reset(self): + self.marks = [] + self.lastindex = -1 + self.marks_stack = [] + self.context_stack = [] + self.repeat = None + + def match(self, pattern_codes): + # XXX INFO optimization missing here + dispatcher = _OpcodeDispatcher() + self.context_stack.append(_MatchContext(self, pattern_codes)) + has_matched = None + while len(self.context_stack) > 0: + context = self.context_stack[-1] + has_matched = dispatcher.match(context) + if has_matched is not None: # don't pop if context isn't done + self.context_stack.pop() + return has_matched + + def search(self, pattern_codes): + if pattern_codes[0] == OPCODES["info"]: + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + # XXX USE_FAST_SEARCH optimizations missing here + # XXX literal and charset optimizations missing here + string_position = self.start + while string_position <= self.end: + self.reset() + self.start = self.string_position = string_position + if self.match(pattern_codes): + return True + string_position += 1 + return False + + def set_mark(self, mark_nr, position): + if mark_nr & 1: + # This id marks the end of a group. + self.lastindex = mark_nr / 2 + 1 + if mark_nr >= len(self.marks): + self.marks.extend([None] * (mark_nr - len(self.marks) + 1)) + self.marks[mark_nr] = position + + def get_marks(self, group_index): + marks_index = 2 * group_index + if len(self.marks) > marks_index + 1: + return self.marks[marks_index], self.marks[marks_index + 1] + else: + return None, None + + def marks_push(self): + self.marks_stack.append((self.marks[:], self.lastindex)) + + def marks_pop(self): + self.marks, self.lastindex = self.marks_stack.pop() + + def marks_pop_keep(self): + self.marks, self.lastindex = self.marks_stack[-1] + + def marks_pop_discard(self): + self.marks_stack.pop() + + def lower(self, char_ord): + return getlower(char_ord, self.flags) + + +class _MatchContext(object): + + def __init__(self, state, pattern_codes): + self.state = state + self.pattern_codes = pattern_codes + self.string_position = state.string_position + self.code_position = 0 + self.has_matched = None + + def push_new_context(self, pattern_offset): + """Creates a new child context of this context and pushes it on the + stack. pattern_offset is the offset off the current code position to + start interpreting from.""" + child_context = _MatchContext(self.state, + self.pattern_codes[self.code_position + pattern_offset:]) + self.state.context_stack.append(child_context) + return child_context + + def peek_char(self, peek=0): + return self.state.string[self.string_position + peek] + + def skip_char(self, skip_count): + self.string_position += skip_count + + def remaining_chars(self): + return self.state.end - self.string_position + + def peek_code(self, peek=0): + return self.pattern_codes[self.code_position + peek] + + def skip_code(self, skip_count): + self.code_position += skip_count + + def remaining_codes(self): + return len(self.pattern_codes) - self.code_position + + def at_beginning(self): + return self.string_position == 0 + + def at_end(self): + return self.string_position == self.state.end + + def at_linebreak(self): + return not self.at_end() and _is_linebreak(self.peek_char()) + + def at_boundary(self, word_checker): + if self.at_beginning() and self.at_end(): + return False + that = not self.at_beginning() and word_checker(self.peek_char(-1)) + this = not self.at_end() and word_checker(self.peek_char()) + return this != that + + +class _RepeatContext(_MatchContext): + + def __init__(self, context): + _MatchContext.__init__(self, context.state, + context.pattern_codes[context.code_position:]) + self.count = -1 + self.previous = context.state.repeat + self.last_position = None + + +class _Dispatcher(object): + + DISPATCH_TABLE = None + + def dispatch(self, code, context): + method = self.DISPATCH_TABLE.get(code, self.__class__.unknown) + return method(self, context) + + def unknown(self, code, ctx): + raise NotImplementedError() + + def build_dispatch_table(cls, code_dict, method_prefix): + table = {} + for key, value in code_dict.items(): + if hasattr(cls, "%s%s" % (method_prefix, key)): + table[value] = getattr(cls, "%s%s" % (method_prefix, key)) + cls.DISPATCH_TABLE = table + + build_dispatch_table = classmethod(build_dispatch_table) + + +class _OpcodeDispatcher(_Dispatcher): + + def __init__(self): + self.executing_contexts = {} + self.at_dispatcher = _AtcodeDispatcher() + self.ch_dispatcher = _ChcodeDispatcher() + self.set_dispatcher = _CharsetDispatcher() + + def match(self, context): + """Returns True if the current context matches, False if it doesn't and + None if matching is not finished, ie must be resumed after child + contexts have been matched.""" + while context.remaining_codes() > 0 and context.has_matched is None: + opcode = context.peek_code() + if not self.dispatch(opcode, context): + return None + if context.has_matched is None: + context.has_matched = False + return context.has_matched + + 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)] + has_finished = generator.next() + else: + method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown) + has_finished = method(self, context) + if hasattr(has_finished, "next"): # avoid using the types module + generator = has_finished + has_finished = generator.next() + if not has_finished: + self.executing_contexts[id(context)] = generator + return has_finished + + def op_success(self, ctx): + # end of pattern + #self._log(ctx, "SUCCESS") + ctx.state.string_position = ctx.string_position + ctx.has_matched = True + return True + + def op_failure(self, ctx): + # immediate failure + #self._log(ctx, "FAILURE") + ctx.has_matched = False + return True + + def general_op_literal(self, ctx, compare, decorate=lambda x: x): + if ctx.at_end() or not compare(decorate(ord(ctx.peek_char())), + decorate(ctx.peek_code(1))): + ctx.has_matched = False + ctx.skip_code(2) + ctx.skip_char(1) + + def op_literal(self, ctx): + # match literal string + # + #self._log(ctx, "LITERAL", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.eq) + return True + + def op_not_literal(self, ctx): + # match anything that is not the given literal character + # + #self._log(ctx, "NOT_LITERAL", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.ne) + return True + + def op_literal_ignore(self, ctx): + # match literal regardless of case + # + #self._log(ctx, "LITERAL_IGNORE", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.eq, ctx.state.lower) + return True + + def op_not_literal_ignore(self, ctx): + # match literal regardless of case + # + #self._log(ctx, "LITERAL_IGNORE", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.ne, ctx.state.lower) + return True + + def op_at(self, ctx): + # match at given position + # + #self._log(ctx, "AT", ctx.peek_code(1)) + if not self.at_dispatcher.dispatch(ctx.peek_code(1), ctx): + ctx.has_matched = False + return True + ctx.skip_code(2) + return True + + def op_category(self, ctx): + # match at given category + # + #self._log(ctx, "CATEGORY", ctx.peek_code(1)) + if ctx.at_end() or not self.ch_dispatcher.dispatch(ctx.peek_code(1), ctx): + ctx.has_matched = False + return True + ctx.skip_code(2) + ctx.skip_char(1) + return True + + def op_any(self, ctx): + # match anything (except a newline) + # + #self._log(ctx, "ANY") + if ctx.at_end() or ctx.at_linebreak(): + ctx.has_matched = False + return True + ctx.skip_code(1) + ctx.skip_char(1) + return True + + def op_any_all(self, ctx): + # match anything + # + #self._log(ctx, "ANY_ALL") + if ctx.at_end(): + ctx.has_matched = False + return True + ctx.skip_code(1) + ctx.skip_char(1) + return True + + def general_op_in(self, ctx, decorate=lambda x: x): + #self._log(ctx, "OP_IN") + if ctx.at_end(): + ctx.has_matched = False + return + skip = ctx.peek_code(1) + ctx.skip_code(2) # set op pointer to the set code + if not self.check_charset(ctx, decorate(ord(ctx.peek_char()))): + ctx.has_matched = False + return + ctx.skip_code(skip - 1) + ctx.skip_char(1) + + def op_in(self, ctx): + # match set member (or non_member) + # + #self._log(ctx, "OP_IN") + self.general_op_in(ctx) + return True + + def op_in_ignore(self, ctx): + # match set member (or non_member), disregarding case of current char + # + #self._log(ctx, "OP_IN_IGNORE") + self.general_op_in(ctx, ctx.state.lower) + return True + + def op_jump(self, ctx): + # jump forward + # + #self._log(ctx, "JUMP", ctx.peek_code(1)) + ctx.skip_code(ctx.peek_code(1) + 1) + return True + + # skip info + # + op_info = op_jump + + def op_mark(self, ctx): + # set mark + # + #self._log(ctx, "OP_MARK", ctx.peek_code(1)) + ctx.state.set_mark(ctx.peek_code(1), ctx.string_position) + ctx.skip_code(2) + return True + + def op_branch(self, ctx): + # alternation + # <0=skip> code ... + #self._log(ctx, "BRANCH") + ctx.state.marks_push() + ctx.skip_code(1) + current_branch_length = ctx.peek_code(0) + while current_branch_length: + # XXX OP_LITERAL and OP_IN optimizations here + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.state.marks_pop_keep() + ctx.skip_code(current_branch_length) + current_branch_length = ctx.peek_code(0) + ctx.state.marks_pop_discard() + ctx.has_matched = False + yield True + + def op_repeat_one(self, ctx): + # match repeated sequence (maximizing). + # this operator only works if the repeated item is exactly one character + # wide, and we're not already collecting backtracking points. + # <1=min> <2=max> item tail + mincount = ctx.peek_code(2) + maxcount = ctx.peek_code(3) + #self._log(ctx, "REPEAT_ONE", mincount, maxcount) + + if ctx.remaining_chars() < mincount: + ctx.has_matched = False + yield True + ctx.state.string_position = ctx.string_position + count = self.count_repetitions(ctx, maxcount) + ctx.skip_char(count) + if count < mincount: + ctx.has_matched = False + yield True + if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: + # tail is empty. we're finished + ctx.state.string_position = ctx.string_position + ctx.has_matched = True + yield True + + # XXX OP_LITERAL optimization missing here + + # backtracking + ctx.state.marks_push() + while count >= mincount: + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.skip_char(-1) + count -= 1 + ctx.state.marks_pop_keep() + + ctx.state.marks_pop_discard() + ctx.has_matched = False + yield True + + def op_min_repeat_one(self, ctx): + # match repeated sequence (minimizing) + # <1=min> <2=max> item tail + mincount = ctx.peek_code(2) + maxcount = ctx.peek_code(3) + #self._log(ctx, "MIN_REPEAT_ONE", mincount, maxcount) + + if ctx.remaining_chars() < mincount: + ctx.has_matched = False + yield True + ctx.state.string_position = ctx.string_position + if mincount == 0: + count = 0 + else: + count = self.count_repetitions(ctx, mincount) + if count < mincount: + ctx.has_matched = False + yield True + ctx.skip_char(count) + if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: + # tail is empty. we're finished + ctx.state.string_position = ctx.string_position + ctx.has_matched = True + yield True + + ctx.state.marks_push() + while maxcount == MAXREPEAT or count <= maxcount: + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.state.string_position = ctx.string_position + if self.count_repetitions(ctx, 1) == 0: + break + ctx.skip_char(1) + count += 1 + ctx.state.marks_pop_keep() + + ctx.state.marks_pop_discard() + ctx.has_matched = False + yield True + + def op_repeat(self, ctx): + # create repeat context. all the hard work is done by the UNTIL + # operator (MAX_UNTIL, MIN_UNTIL) + # <1=min> <2=max> item tail + #self._log(ctx, "REPEAT", ctx.peek_code(2), ctx.peek_code(3)) + repeat = _RepeatContext(ctx) + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + ctx.state.repeat = repeat.previous + ctx.has_matched = child_context.has_matched + yield True + + def op_max_until(self, ctx): + # maximizing repeat + # <1=min> <2=max> item tail + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + #self._log(ctx, "MAX_UNTIL", count) + + if count < mincount: + # not enough matches + repeat.count = count + child_context = repeat.push_new_context(4) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + yield True + + if (count < maxcount or maxcount == MAXREPEAT) \ + and ctx.state.string_position != repeat.last_position: + # we may have enough matches, if we can match another item, do so + repeat.count = count + ctx.state.marks_push() + save_last_position = repeat.last_position # zero-width match protection + repeat.last_position = ctx.state.string_position + child_context = repeat.push_new_context(4) + yield False + repeat.last_position = save_last_position + if child_context.has_matched: + ctx.state.marks_pop_discard() + ctx.has_matched = True + yield True + ctx.state.marks_pop() + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + + # cannot match more repeated items here. make sure the tail matches + ctx.state.repeat = repeat.previous + child_context = ctx.push_new_context(1) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + yield True + + def op_min_until(self, ctx): + # minimizing repeat + # <1=min> <2=max> item tail + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + #self._log(ctx, "MIN_UNTIL", count) + + if count < mincount: + # not enough matches + repeat.count = count + child_context = repeat.push_new_context(4) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + yield True + + # see if the tail matches + ctx.state.marks_push() + ctx.state.repeat = repeat.previous + child_context = ctx.push_new_context(1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + ctx.state.marks_pop() + + # match more until tail matches + if count >= maxcount and maxcount != MAXREPEAT: + ctx.has_matched = False + yield True + repeat.count = count + child_context = repeat.push_new_context(4) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + yield True + + def general_op_groupref(self, ctx, decorate=lambda x: x): + group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) + if group_start is None or group_end is None or group_end < group_start: + ctx.has_matched = False + return True + while group_start < group_end: + if ctx.at_end() or decorate(ord(ctx.peek_char())) \ + != decorate(ord(ctx.state.string[group_start])): + ctx.has_matched = False + return True + group_start += 1 + ctx.skip_char(1) + ctx.skip_code(2) + return True + + def op_groupref(self, ctx): + # match backreference + # + #self._log(ctx, "GROUPREF", ctx.peek_code(1)) + return self.general_op_groupref(ctx) + + def op_groupref_ignore(self, ctx): + # match backreference case-insensitive + # + #self._log(ctx, "GROUPREF_IGNORE", ctx.peek_code(1)) + return self.general_op_groupref(ctx, ctx.state.lower) + + def op_groupref_exists(self, ctx): + # codeyes codeno ... + #self._log(ctx, "GROUPREF_EXISTS", ctx.peek_code(1)) + group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) + if group_start is None or group_end is None or group_end < group_start: + ctx.skip_code(ctx.peek_code(2) + 1) + else: + ctx.skip_code(3) + return True + + def op_assert(self, ctx): + # assert subpattern + # + #self._log(ctx, "ASSERT", ctx.peek_code(2)) + ctx.state.string_position = ctx.string_position - ctx.peek_code(2) + if ctx.state.string_position < 0: + ctx.has_matched = False + yield True + child_context = ctx.push_new_context(3) + yield False + if child_context.has_matched: + ctx.skip_code(ctx.peek_code(1) + 1) + else: + ctx.has_matched = False + yield True + + def op_assert_not(self, ctx): + # assert not subpattern + # + #self._log(ctx, "ASSERT_NOT", ctx.peek_code(2)) + ctx.state.string_position = ctx.string_position - ctx.peek_code(2) + if ctx.state.string_position >= 0: + child_context = ctx.push_new_context(3) + yield False + if child_context.has_matched: + ctx.has_matched = False + yield True + ctx.skip_code(ctx.peek_code(1) + 1) + yield True + + def unknown(self, ctx): + #self._log(ctx, "UNKNOWN", ctx.peek_code()) + raise RuntimeError("Internal re error. Unknown opcode: %s" % ctx.peek_code()) + + def check_charset(self, ctx, char): + """Checks whether a character matches set of arbitrary length. Assumes + the code pointer is at the first member of the set.""" + self.set_dispatcher.reset(char) + save_position = ctx.code_position + result = None + while result is None: + result = self.set_dispatcher.dispatch(ctx.peek_code(), ctx) + ctx.code_position = save_position + return result + + def count_repetitions(self, ctx, maxcount): + """Returns the number of repetitions of a single item, starting from the + current string position. The code pointer is expected to point to a + REPEAT_ONE operation (with the repeated 4 ahead).""" + count = 0 + real_maxcount = ctx.state.end - ctx.string_position + if maxcount < real_maxcount and maxcount != MAXREPEAT: + real_maxcount = maxcount + # XXX could special case every single character pattern here, as in C. + # This is a general solution, a bit hackisch, but works and should be + # efficient. + code_position = ctx.code_position + string_position = ctx.string_position + ctx.skip_code(4) + reset_position = ctx.code_position + while count < real_maxcount: + # this works because the single character pattern is followed by + # a success opcode + ctx.code_position = reset_position + self.dispatch(ctx.peek_code(), ctx) + if ctx.has_matched is False: # could be None as well + break + count += 1 + ctx.has_matched = None + ctx.code_position = code_position + ctx.string_position = string_position + return count + + def _log(self, context, opname, *args): + arg_string = ("%s " * len(args)) % args + _log("|%s|%s|%s %s" % (context.pattern_codes, + context.string_position, opname, arg_string)) + +_OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") + + +class _CharsetDispatcher(_Dispatcher): + + def __init__(self): + self.ch_dispatcher = _ChcodeDispatcher() + + def reset(self, char): + self.char = char + self.ok = True + + def set_failure(self, ctx): + return not self.ok + def set_literal(self, ctx): + # + if ctx.peek_code(1) == self.char: + return self.ok + else: + ctx.skip_code(2) + def set_category(self, ctx): + # + if self.ch_dispatcher.dispatch(ctx.peek_code(1), ctx): + return self.ok + else: + ctx.skip_code(2) + def set_charset(self, ctx): + # (16 bits per code word) + char_code = self.char + ctx.skip_code(1) # point to beginning of bitmap + if CODESIZE == 2: + if char_code < 256 and ctx.peek_code(char_code >> 4) \ + & (1 << (char_code & 15)): + return self.ok + ctx.skip_code(16) # skip bitmap + else: + if char_code < 256 and ctx.peek_code(char_code >> 5) \ + & (1 << (char_code & 31)): + return self.ok + ctx.skip_code(8) # skip bitmap + def set_range(self, ctx): + # + if ctx.peek_code(1) <= self.char <= ctx.peek_code(2): + return self.ok + ctx.skip_code(3) + def set_negate(self, ctx): + self.ok = not self.ok + ctx.skip_code(1) + def set_bigcharset(self, ctx): + # <256 blockindices> + char_code = self.char + count = ctx.peek_code(1) + ctx.skip_code(2) + if char_code < 65536: + block_index = char_code >> 8 + # NB: there are CODESIZE block indices per bytecode + a = array.array("B") + a.fromstring(array.array(CODESIZE == 2 and "H" or "I", + [ctx.peek_code(block_index / CODESIZE)]).tostring()) + block = a[block_index % CODESIZE] + ctx.skip_code(256 / CODESIZE) # skip block indices + block_value = ctx.peek_code(block * (32 / CODESIZE) + + ((char_code & 255) >> (CODESIZE == 2 and 4 or 5))) + if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): + return self.ok + else: + ctx.skip_code(256 / CODESIZE) # skip block indices + ctx.skip_code(count * (32 / CODESIZE)) # skip blocks + def unknown(self, ctx): + return False + + +_CharsetDispatcher.build_dispatch_table(OPCODES, "set_") + + +class _AtcodeDispatcher(_Dispatcher): + + def at_beginning(self, ctx): + return ctx.at_beginning() + at_beginning_string = at_beginning + def at_beginning_line(self, ctx): + return ctx.at_beginning() or _is_linebreak(ctx.peek_char(-1)) + def at_end(self, ctx): + return (ctx.remaining_chars() == 1 and ctx.at_linebreak()) or ctx.at_end() + def at_end_line(self, ctx): + return ctx.at_linebreak() or ctx.at_end() + def at_end_string(self, ctx): + return ctx.at_end() + def at_boundary(self, ctx): + return ctx.at_boundary(_is_word) + def at_non_boundary(self, ctx): + return not ctx.at_boundary(_is_word) + def at_loc_boundary(self, ctx): + return ctx.at_boundary(_is_loc_word) + def at_loc_non_boundary(self, ctx): + return not ctx.at_boundary(_is_loc_word) + def at_uni_boundary(self, ctx): + return ctx.at_boundary(_is_uni_word) + def at_uni_non_boundary(self, ctx): + return not ctx.at_boundary(_is_uni_word) + def unknown(self, ctx): + return False + +_AtcodeDispatcher.build_dispatch_table(ATCODES, "") + + +class _ChcodeDispatcher(_Dispatcher): + + def category_digit(self, ctx): + return _is_digit(ctx.peek_char()) + def category_not_digit(self, ctx): + return not _is_digit(ctx.peek_char()) + def category_space(self, ctx): + return _is_space(ctx.peek_char()) + def category_not_space(self, ctx): + return not _is_space(ctx.peek_char()) + def category_word(self, ctx): + return _is_word(ctx.peek_char()) + def category_not_word(self, ctx): + return not _is_word(ctx.peek_char()) + def category_linebreak(self, ctx): + return _is_linebreak(ctx.peek_char()) + def category_not_linebreak(self, ctx): + return not _is_linebreak(ctx.peek_char()) + def category_loc_word(self, ctx): + return _is_loc_word(ctx.peek_char()) + def category_loc_not_word(self, ctx): + return not _is_loc_word(ctx.peek_char()) + def category_uni_digit(self, ctx): + return ctx.peek_char().isdigit() + def category_uni_not_digit(self, ctx): + return not ctx.peek_char().isdigit() + def category_uni_space(self, ctx): + return ctx.peek_char().isspace() + def category_uni_not_space(self, ctx): + return not ctx.peek_char().isspace() + def category_uni_word(self, ctx): + return _is_uni_word(ctx.peek_char()) + def category_uni_not_word(self, ctx): + return not _is_uni_word(ctx.peek_char()) + def category_uni_linebreak(self, ctx): + return ord(ctx.peek_char()) in _uni_linebreaks + def category_uni_not_linebreak(self, ctx): + return ord(ctx.peek_char()) not in _uni_linebreaks + def unknown(self, ctx): + return False + +_ChcodeDispatcher.build_dispatch_table(CHCODES, "") + + +_ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, +2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, +0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 ] + +def _is_digit(char): + code = ord(char) + return code < 128 and _ascii_char_info[code] & 1 + +def _is_space(char): + code = ord(char) + return code < 128 and _ascii_char_info[code] & 2 + +def _is_word(char): + # NB: non-ASCII chars aren't words according to _sre.c + code = ord(char) + return code < 128 and _ascii_char_info[code] & 16 + +def _is_loc_word(char): + return (not (ord(char) & ~255) and char.isalnum()) or char == '_' + +def _is_uni_word(char): + return char.isalnum() or char == '_' + +def _is_linebreak(char): + return char == "\n" + +# Static list of all unicode codepoints reported by Py_UNICODE_ISLINEBREAK. +_uni_linebreaks = [10, 13, 28, 29, 30, 133, 8232, 8233] + +def _log(message): + if 0: + print message From cfbolz at codespeak.net Tue Aug 2 20:47:23 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 2 Aug 2005 20:47:23 +0200 (CEST) Subject: [pypy-svn] r15522 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050802184723.A46B127B4B@code1.codespeak.net> Author: cfbolz Date: Tue Aug 2 20:47:19 2005 New Revision: 15522 Modified: pypy/dist/pypy/rpython/memory/simulator.py pypy/dist/pypy/rpython/memory/test/test_simulator.py Log: added a size of RAM to the memory simulator to be able to simulate out of memory situations. Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Tue Aug 2 20:47:19 2005 @@ -3,6 +3,7 @@ # all addresses in the simulator are just ints + # possible chars in status are: # 'u': uninitialized # 'i': initialized @@ -50,9 +51,12 @@ assert len(self.memory) == self.size class MemorySimulator(object): - def __init__(self): + size_of_simulated_ram = 64 * 1024 * 1024 + def __init__(self, ram_size = None): self.blocks = [] self.freememoryaddress = 4 + if ram_size is not None: + self.size_of_simulated_ram = ram_size def find_block(self, address): lo = 0 @@ -72,6 +76,8 @@ result = self.freememoryaddress self.blocks.append(MemoryBlock(result, size)) self.freememoryaddress += size + if self.freememoryaddress > self.size_of_simulated_ram: + raise MemorySimulatorError, "out of memory" return result def free(self, baseaddress): Modified: pypy/dist/pypy/rpython/memory/test/test_simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_simulator.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_simulator.py Tue Aug 2 20:47:19 2005 @@ -1,5 +1,9 @@ import py -from pypy.rpython.memory.simulator import * +from pypy.rpython.memory.simulator import MemoryBlock, MemorySimulator +from pypy.rpython.memory.simulator import MemorySimulatorError +from pypy.rpython.memory import simulator + +import struct class TestMemoryBlock(object): def test_getsetbyte(self): @@ -55,3 +59,10 @@ assert simulator.getstruct("iii", addr1) == (1, 2, 3) assert simulator.getstruct("iii", addr1 + 500) == (1, 2, 3) assert simulator.getstruct("iii", addr2) == (1, 2, 3) + + def test_out_of_memory(self): + sim = MemorySimulator(1 * 1024 * 1024) + def f(): + for i in xrange(10000000): + sim.malloc(4096) + py.test.raises(MemorySimulatorError, f) From cfbolz at codespeak.net Tue Aug 2 22:27:52 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 2 Aug 2005 22:27:52 +0200 (CEST) Subject: [pypy-svn] r15524 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050802202752.7BDB927B53@code1.codespeak.net> Author: cfbolz Date: Tue Aug 2 22:27:47 2005 New Revision: 15524 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: enhanced the lltypesimulation in the following ways: - added array support - added support for structs with inlined arrays - added cast_pointer - tests for the above Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Tue Aug 2 22:27:47 2005 @@ -1,39 +1,70 @@ +import py + from pypy.rpython.memory import lladdress from pypy.rpython import lltype import struct +log = py.log.Producer("lltypesim") + primitive_to_fmt = {lltype.Signed: "i", lltype.Unsigned: "I", lltype.Char: "c", } +#returns some sort of layout information that is useful for the simulatorptr def get_layout(TYPE): layout = {} if isinstance(TYPE, lltype.Primitive): return primitive_to_fmt[TYPE] - if isinstance(TYPE, lltype.Ptr): + elif isinstance(TYPE, lltype.Ptr): return "P" - if isinstance(TYPE, lltype.Struct): + elif isinstance(TYPE, lltype.Struct): curr = 0 for name in TYPE._names: layout[name] = curr - curr += get_size(TYPE._flds[name]) + curr += get_fixed_size(TYPE._flds[name]) layout["_size"] = curr return layout + elif isinstance(TYPE, lltype.Array): + return (get_fixed_size(lltype.Signed), get_fixed_size(TYPE.OF)) else: assert 0, "not yet implemented" -def get_size(TYPE): +def get_fixed_size(TYPE): if isinstance(TYPE, lltype.Primitive): return struct.calcsize(primitive_to_fmt[TYPE]) elif isinstance(TYPE, lltype.Ptr): return struct.calcsize("P") elif isinstance(TYPE, lltype.Struct): return get_layout(TYPE)["_size"] + elif isinstance(TYPE, lltype.Array): + return get_fixed_size(lltype.Unsigned) + assert 0, "not yet implemented" + +def get_variable_size(TYPE): + if isinstance(TYPE, lltype.Array): + return get_fixed_size(TYPE.OF) + elif isinstance(TYPE, lltype.Primitive): + return 0 + elif isinstance(TYPE, lltype.Struct): + if isinstance(TYPE._flds[TYPE._names[-1]], lltype.Array): + return get_variable_size(TYPE._flds[TYPE._arrayfld]) + else: + return 0 else: assert 0, "not yet implemented" - + +def _expose(T, address): + """XXX A nice docstring here""" + if isinstance(T, (lltype.Struct, lltype.Array)): + return simulatorptr(lltype.Ptr(T), address) + elif isinstance(T, lltype.Primitive): + return address._load(primitive_to_fmt[T]) + else: + assert 0, "not implemented yet" + + # this class is intended to replace the _ptr class in lltype # using the memory simulator class simulatorptr(object): @@ -42,12 +73,27 @@ self.__dict__['_T'] = TYPE.TO self.__dict__['_address'] = address self.__dict__['_layout'] = get_layout(TYPE.TO) - self._zero_initialize() - def _zero_initialize(self): - size = get_size(self._T) + def _zero_initialize(self, i=None): + fixedsize = get_fixed_size(self._T) + varsize = get_variable_size(self._T) + if i is None: + assert varsize == 0 + size = fixedsize + else: + size = fixedsize + i * varsize self._address._store("c" * size, *(["\x00"] * size)) + def _init_size(self, size): + if isinstance(self._T, lltype.Array): + self._address.signed[0] = size + elif isinstance(self._T, lltype.Struct): + if isinstance(self._T._flds[self._T._names[-1]], lltype.Array): + addr = self._address + self._layout[self._T._arrayfld] + addr.signed[0] = size + else: + assert size is None, "setting not implemented" + def __getattr__(self, field_name): if isinstance(self._T, lltype.Struct): offset = self._layout[field_name] @@ -55,7 +101,14 @@ T = self._T._flds[field_name] base = self._layout[field_name] if isinstance(T, lltype.Primitive): - return (self._address + offset)._load(primitive_to_fmt[T])[0] + res = (self._address + offset)._load(primitive_to_fmt[T])[0] + return res + elif isinstance(T, lltype.Ptr): + res = _expose(T.TO, (self._address + offset).address[0]) + return res + elif isinstance(T, lltype.ContainerType): + res = _expose(T, (self._address + offset)) + return res else: assert 0, "not implemented" raise AttributeError, ("%r instance has no field %r" % (self._T, @@ -65,18 +118,93 @@ if isinstance(self._T, lltype.Struct): if field_name in self._T._flds: T = self._T._flds[field_name] - base = self._layout[field_name] + offset = self._layout[field_name] if isinstance(T, lltype.Primitive): - (self._address + base)._store(primitive_to_fmt[T], value) + (self._address + offset)._store(primitive_to_fmt[T], value) + return + elif isinstance(T, lltype.Ptr): + assert value._TYPE == T + (self._address + offset).address[0] = value._address return else: assert 0, "not implemented" raise AttributeError, ("%r instance has no field %r" % (self._T, field_name)) + def __getitem__(self, i): + if isinstance(self._T, lltype.Array): + if not (0 <= i < self._address.signed[0]): + raise IndexError, "array index out of bounds" + addr = self._address + self._layout[0] + i * self._layout[1] + return _expose(self._T.OF, addr) + raise TypeError("%r instance is not an array" % (self._T,)) + + def __setitem__(self, i, value): + if isinstance(self._T, lltype.Array): + T1 = self._T.OF + if isinstance(T1, lltype.ContainerType): + s = "cannot directly assign to container array items" + raise TypeError, s + T2 = typeOf(val) + if T2 != T1: + raise TypeError("%r items:\n" + "expect %r\n" + " got %r" % (self._T, T1, T2)) + if not (0 <= i < self._address.signed[0]): + raise IndexError, "array index out of bounds" + self._address._store(get_layout(self._T.OF), value) + return + raise TypeError("%r instance is not an array" % (self._T,)) + + def __len__(self): + if isinstance(self._T, lltype.Array): + return self._address.signed[0] + raise TypeError("%r instance is not an array" % (self._T,)) + + def __nonzero__(self): + return self._address != lladdres.NULL + + def __eq__(self, other): + if not isinstance(other, simulatorptr): + raise TypeError("comparing pointer with %r object" % ( + type(other).__name__,)) + if self._TYPE != other._TYPE: + raise TypeError("comparing %r and %r" % (self._TYPE, other._TYPE)) + return self._address == other._address + + def __repr__(self): + addr = self._address.intaddress + if addr < 0: + addr += 256 ** struct.calcsize("P") + return '' % (self._TYPE.TO, addr) + + +def cast_pointer(PTRTYPE, ptr): + if not isinstance(ptr, simulatorptr) or not isinstance(PTRTYPE, lltype.Ptr): + raise TypeError, "can only cast pointers to other pointers" + CURTYPE = ptr._TYPE + down_or_up = lltype.castable(PTRTYPE, CURTYPE) + if down_or_up == 0: + return ptr + # XXX the lltype.cast_pointer does a lot of checks here: + # I can't think of a way to do that with simulatorptr. + # I'm not sure whether this is the right way to go... + return simulatorptr(PTRTYPE, ptr._address) + + # for now use the simulators raw_malloc def malloc(T, n=None, immortal=False): - size = get_size(T) + fixedsize = get_fixed_size(T) + varsize = get_variable_size(T) + if n is None: + if varsize: + raise TypeError, "%r is variable-sized" % (T,) + size = fixedsize + else: + size = fixedsize + n * varsize address = lladdress.raw_malloc(size) - return simulatorptr(lltype.Ptr(T), address) + result = simulatorptr(lltype.Ptr(T), address) + result._zero_initialize(n) + result._init_size(n) + return result Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Tue Aug 2 22:27:47 2005 @@ -1,10 +1,11 @@ from pypy.rpython.memory.lltypesimulation import * -from pypy.rpython.lltype import GcStruct, Ptr, Signed, Char + +py.log.setconsumer("lltypesim", None) def test_struct(): - S0 = GcStruct("s0", ('a', Signed), ('b', Signed), ('c', Char)) + S0 = lltype.GcStruct("s0", ('a', lltype.Signed), + ('b', lltype.Signed), ('c', lltype.Char)) s0 = malloc(S0) - print s0 assert s0.a == 0 assert s0.b == 0 assert s0.c == '\x00' @@ -19,17 +20,114 @@ assert s0.a == 1 assert s0.b == 1 -def DONOTtest_array(): - Ar = lltype.GcArray(('v', Signed)) - x = malloc(Ar,0) - print x +def test_array(): + Ar = lltype.GcArray(('v', lltype.Signed)) + x = malloc(Ar, 0) assert len(x) == 0 - x = malloc(Ar,3) - print x - assert typeOf(x) == Ptr(Ar) - assert typeOf(x[0].v) == Signed + x = malloc(Ar, 3) + assert lltype.typeOf(x) == lltype.Ptr(Ar) + assert lltype.typeOf(x[0].v) == lltype.Signed assert x[0].v == 0 x[0].v = 1 x[1].v = 2 x[2].v = 3 assert [x[z].v for z in range(3)] == [1, 2, 3] + + + +def define_list(T): + List_typ = lltype.GcStruct( + "list", ("items", lltype.Ptr(lltype.GcArray(('item',T))))) + def newlist(): + l = malloc(List_typ) + items = malloc(List_typ.items.TO, 0) + l.items = items + return l + + def append(l, newitem): + length = len(l.items) + newitems = malloc(List_typ.items.TO, length+1) + i = 0 + while i Author: rxe Date: Wed Aug 3 01:20:17 2005 New Revision: 15527 Modified: pypy/dist/pypy/translator/llvm2/structnode.py Log: Ooops - last checkin suppose to read: Fixed howler - that was preventing richards from running. Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Wed Aug 3 01:20:17 2005 @@ -212,4 +212,3 @@ refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref) ref = "cast(%s %s to %s)" % (fromptr, refptr, toptr) return ref - From rxe at codespeak.net Wed Aug 3 01:21:13 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 01:21:13 +0200 (CEST) Subject: [pypy-svn] r15528 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050802232113.7CC9B27B4D@code1.codespeak.net> Author: rxe Date: Wed Aug 3 01:21:12 2005 New Revision: 15528 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py Log: More readable char array constants. Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Wed Aug 3 01:21:12 2005 @@ -89,12 +89,14 @@ items = self.value.items return len(items) - def get_arrayvalues(self): + def get_arrayvalue(self): items = self.value.items - return [self.db.repr_constant(v)[1] for v in items] + l = len(items) + r = "[%s]" % ", ".join([self.db.repr_constant(v)[1] for v in items]) + return l, r def get_typerepr(self): - arraylen = len(self.get_arrayvalues()) + arraylen = self.get_arrayvalue()[0] typeval = self.db.repr_arg_type(self.arraytype) return "{ int, [%s x %s] }" % (arraylen, typeval) @@ -127,37 +129,48 @@ index) def constantvalue(self): - arrayvalues = self.get_arrayvalues() + physicallen, arrayrepr = self.get_arrayvalue() typeval = self.db.repr_arg_type(self.arraytype) # first length is logical, second is physical - value = "int %s, [%s x %s] [ %s ]" % (self.get_length(), - len(arrayvalues), + value = "int %s, [%s x %s] %s" % (self.get_length(), + physicallen, typeval, - ", ".join(arrayvalues)) + arrayrepr) s = "%s {%s}" % (self.get_typerepr(), value) return s class StrArrayNode(ArrayNode): + printables = dict([(ord(i), None) for i in + ("0123456789abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "!#$%&()*+,-./:;<=>?@[\\]^_`{|}~ '")]) - def get_arrayvalues(self): + def get_arrayvalue(self): items = self.value.items - if len(items) == 0 or items[-1] != chr(0): + item_length = len(items) + if item_length == 0 or items[-1] != chr(0): items = items + [chr(0)] - return [self.db.repr_constant(v)[1] for v in items] + l = item_length + 1 + r = "".join([self.db.repr_constant(v)[1] for v in items]) + return l, r - def constantvalue(self): - #XXX this does not work for arrays inlined in struct. How else to do this? - # limited_printable = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/-.' - # s += ' ;"' - # for item in items: - # if item in limited_printable: - # s += item - # else: - # s += '_' - # s += '" ' - return super(StrArrayNode, self).constantvalue() + def get_arrayvalue(self): + items = self.value.items + item_length = len(items) + if item_length == 0 or items[-1] != chr(0): + items = items + [chr(0)] + l = item_length + 1 + s = [] + for c in items: + if ord(c) in StrArrayNode.printables: + s.append(c) + else: + s.append("\\%02x" % ord(c)) + + r = 'c"%s"' % "".join(s) + return l, r class VoidArrayNode(ConstantLLVMNode): From rxe at codespeak.net Wed Aug 3 01:22:35 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 01:22:35 +0200 (CEST) Subject: [pypy-svn] r15529 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050802232235.CCC1127B4B@code1.codespeak.net> Author: rxe Date: Wed Aug 3 01:22:34 2005 New Revision: 15529 Modified: pypy/dist/pypy/translator/llvm2/opwriter.py Log: re-oops this was fix for richards. gnite. Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 3 01:22:34 2005 @@ -335,14 +335,24 @@ self.codewriter.call(targetvar, struct_type + "*", struct_cons, argrefs, argtypes) + def _getindexhelper(self, name, struct): + assert name in list(struct._names) + + fieldnames = struct._names_without_voids() + try: + index = fieldnames.index(name) + except ValueError: + index = -1 + return index + def getfield(self, op): tmpvar = self.db.repr_tmpvar() struct, structtype = self.db.repr_argwithtype(op.args[0]) - fieldnames = list(op.args[0].concretetype.TO._names) - index = fieldnames.index(op.args[1].value) + index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO) targetvar = self.db.repr_arg(op.result) targettype = self.db.repr_arg_type(op.result) if targettype != "void": + assert index != -1 self.codewriter.getelementptr(tmpvar, structtype, struct, ("uint", index)) self.codewriter.load(targetvar, targettype, tmpvar) @@ -351,8 +361,7 @@ def getsubstruct(self, op): struct, structtype = self.db.repr_argwithtype(op.args[0]) - fieldnames = list(op.args[0].concretetype.TO._names) - index = fieldnames.index(op.args[1].value) + index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO) targetvar = self.db.repr_arg(op.result) targettype = self.db.repr_arg_type(op.result) assert targettype != "void" @@ -362,8 +371,7 @@ def setfield(self, op): tmpvar = self.db.repr_tmpvar() struct, structtype = self.db.repr_argwithtype(op.args[0]) - fieldnames = list(op.args[0].concretetype.TO._names) - index = fieldnames.index(op.args[1].value) + index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO) valuevar, valuetype = self.db.repr_argwithtype(op.args[2]) if valuetype != "void": self.codewriter.getelementptr(tmpvar, structtype, struct, From ericvrp at codespeak.net Wed Aug 3 01:43:27 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 01:43:27 +0200 (CEST) Subject: [pypy-svn] r15530 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050802234327.2213927B4D@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 01:43:25 2005 New Revision: 15530 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/pyxwrapper.py pypy/dist/pypy/translator/llvm2/test/test_exception.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: - added entrypoint wrapper function to handle llvm->CPython exception conversions (very basic right now) - added calling convention (ccc/fastcc) to enable llvm to do its magic with functioncalls Last remaining exceptions test now passes! The test that is left is skipped because the interpreter does not like it. Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Wed Aug 3 01:43:25 2005 @@ -46,7 +46,7 @@ ", ".join(argtypereprs))) def declare(self, decl): - self.append("declare %s" %(decl,)) + self.append("declare fastcc %s" %(decl,)) def startimpl(self): self.newline() @@ -69,7 +69,7 @@ def openfunc(self, decl): self.newline() - self.append("%s {" % (decl,)) + self.append("fastcc %s {" % (decl,)) def closefunc(self): self.append("}") @@ -99,21 +99,21 @@ def call(self, targetvar, returntype, functionref, argrefs, argtypes): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("%s = call %s %s(%s)" % (targetvar, returntype, functionref, + self.indent("%s = call fastcc %s %s(%s)" % (targetvar, returntype, functionref, ", ".join(arglist))) def call_void(self, functionref, argrefs, argtypes): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("call void %s(%s)" % (functionref, ", ".join(arglist))) + self.indent("call fastcc void %s(%s)" % (functionref, ", ".join(arglist))) def invoke(self, targetvar, returntype, functionref, argrefs, argtypes, label, except_label): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("%s = invoke %s %s(%s) to label %%%s except label %%%s" % (targetvar, returntype, functionref, + self.indent("%s = invoke fastcc %s %s(%s) to label %%%s except label %%%s" % (targetvar, returntype, functionref, ", ".join(arglist), label, except_label)) def invoke_void(self, functionref, argrefs, argtypes, label, except_label): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("invoke void %s(%s) to label %%%s except label %%%s" % (functionref, ", ".join(arglist), label, except_label)) + self.indent("invoke fastcc void %s(%s) to label %%%s except label %%%s" % (functionref, ", ".join(arglist), label, except_label)) def cast(self, targetvar, fromtype, fromvar, targettype): self.indent("%(targetvar)s = cast %(fromtype)s " @@ -124,7 +124,7 @@ postfix = ('', '_atomic')[atomic] self.indent("%%malloc.Size.%(cnt)d = getelementptr %(type_)s* null, uint %(size)s" % locals()) self.indent("%%malloc.SizeU.%(cnt)d = cast %(type_)s* %%malloc.Size.%(cnt)d to uint" % locals()) - self.indent("%%malloc.Ptr.%(cnt)d = call sbyte* %%gc_malloc%(postfix)s(uint %%malloc.SizeU.%(cnt)d)" % locals()) + self.indent("%%malloc.Ptr.%(cnt)d = call fastcc sbyte* %%gc_malloc%(postfix)s(uint %%malloc.SizeU.%(cnt)d)" % locals()) self.indent("%(targetvar)s = cast sbyte* %%malloc.Ptr.%(cnt)d to %(type_)s*" % locals()) def getelementptr(self, targetvar, type, typevar, *indices): @@ -140,7 +140,7 @@ "%(valuetype)s* %(ptr)s" % locals()) def debugcomment(self, tempname, len, tmpname): - res = "%s = tail call int (sbyte*, ...)* %%printf(" + res = "%s = tail call ccc int (sbyte*, ...)* %%printf(" res += "sbyte* getelementptr ([%s x sbyte]* %s, int 0, int 0) )" res = res % (tmpname, len, tmpname) self.indent(res) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Wed Aug 3 01:43:25 2005 @@ -23,6 +23,8 @@ class GenLLVM(object): def __init__(self, translator, debug=False, embedexterns=True): + embedexterns = True # XXX just for now because exception handling globals must be available + # reset counters LLVMNode.nodename_count = {} self.db = Database(translator) @@ -90,8 +92,8 @@ gc_funcs = gc_boehm else: gc_funcs = gc_disabled - for extfunc in gc_funcs.split('\n'): - codewriter.append(extfunc) + for gc_func in gc_funcs.split('\n'): + codewriter.append(gc_func) for typ_decl in self.db.getnodes(): typ_decl.writeimpl(codewriter) @@ -110,6 +112,34 @@ codewriter.append(extfunc) depdone[dep] = True + #XXX use codewriter methods here + decl = self.entrynode.getdecl() + t = decl.split('%', 1) + if t[0] == 'double ': #XXX I know, I know... refactor at will! + no_result = '0.0' + elif t[0] == 'bool ': + no_result = 'false' + else: + no_result = '0' + codewriter.newline() + codewriter.append("ccc %s%%__entrypoint__%s {" % (t[0], t[1])) + codewriter.append(" %%result = invoke fastcc %s%%%s to label %%no_exception except label %%exception" % (t[0], t[1])) + codewriter.newline() + codewriter.append("no_exception:") + codewriter.append(" store %structtype.object_vtable* null, %structtype.object_vtable** %last_exception_type") + codewriter.append(" ret %s%%result" % t[0]) + codewriter.newline() + codewriter.append("exception:") + codewriter.append(" ret %s%s" % (t[0], no_result)) + codewriter.append("}") + codewriter.newline() + codewriter.append("ccc int %__entrypoint__raised_LLVMException() {") + codewriter.append(" %tmp = load %structtype.object_vtable** %last_exception_type") + codewriter.append(" %result = cast %structtype.object_vtable* %tmp to int") + codewriter.append(" ret int %result") + codewriter.append("}") + codewriter.newline() + comment("End of file") ; nl() self.content = str(codewriter) return self.content @@ -127,7 +157,7 @@ targetdir = udir llvmsource = targetdir.join(func.func_name+postfix).new(ext='.ll') - llvmsource.write(self.content) + llvmsource.write(self.content) # XXX writing to disc directly would conserve memory if not llvm_is_on_path(): py.test.skip("llvm not found") # XXX not good to call py.test.skip here Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Wed Aug 3 01:43:25 2005 @@ -1,35 +1,35 @@ -extdeclarations = """;gc-type dependent mallocs -declare sbyte* %gc_malloc(uint) -declare sbyte* %gc_malloc_atomic(uint) - -;rpython stuff +extdeclarations = """;rpython stuff %structtype.rpy_string = type {int, {int, [0 x sbyte]}} +;gc-type dependent mallocs +declare fastcc sbyte* %gc_malloc(uint) +declare fastcc sbyte* %gc_malloc_atomic(uint) + ;exception handling globals %last_exception_type = global %structtype.object_vtable* null %last_exception_value = global %structtype.object* null """ -gc_boehm = """declare sbyte* %GC_malloc(uint) -declare sbyte* %GC_malloc_atomic(uint) +gc_boehm = """declare ccc sbyte* %GC_malloc(uint) +declare ccc sbyte* %GC_malloc_atomic(uint) -sbyte* %gc_malloc(uint %n) { - %ptr = call sbyte* %GC_malloc(uint %n) +fastcc sbyte* %gc_malloc(uint %n) { + %ptr = call ccc sbyte* %GC_malloc(uint %n) ret sbyte* %ptr } -sbyte* %gc_malloc_atomic(uint %n) { - %ptr = call sbyte* %GC_malloc_atomic(uint %n) +fastcc sbyte* %gc_malloc_atomic(uint %n) { + %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) ret sbyte* %ptr } """ -gc_disabled = """sbyte* %gc_malloc(uint %n) { +gc_disabled = """fastcc sbyte* %gc_malloc(uint %n) { %ptr = malloc sbyte, uint %n ret sbyte* %ptr } -sbyte* %gc_malloc_atomic(uint %n) { +fastcc sbyte* %gc_malloc_atomic(uint %n) { %ptr = malloc sbyte, uint %n ret sbyte* %ptr } Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Wed Aug 3 01:43:25 2005 @@ -1,23 +1,23 @@ extdeclarations = """ ;ll_math.py -declare double %acos(double) -declare double %asin(double) -declare double %atan(double) -declare double %ceil(double) -declare double %cos(double) -declare double %cosh(double) -declare double %exp(double) -declare double %fabs(double) -declare double %floor(double) -declare double %log(double) -declare double %log10(double) -declare double %sin(double) -declare double %sinh(double) -declare double %sqrt(double) -declare double %tan(double) -declare double %tanh(double) -declare double %atan2(double,double) -declare double %fmod(double,double) +declare ccc double %acos(double) +declare ccc double %asin(double) +declare ccc double %atan(double) +declare ccc double %ceil(double) +declare ccc double %cos(double) +declare ccc double %cosh(double) +declare ccc double %exp(double) +declare ccc double %fabs(double) +declare ccc double %floor(double) +declare ccc double %log(double) +declare ccc double %log10(double) +declare ccc double %sin(double) +declare ccc double %sinh(double) +declare ccc double %sqrt(double) +declare ccc double %tan(double) +declare ccc double %tanh(double) +declare ccc double %atan2(double,double) +declare ccc double %fmod(double,double) """ extfunctions = {} @@ -30,8 +30,8 @@ ] simple_function_template = """ -double %%ll_math_%(function)s(%(params)s) { - %%t = call double %%%(function)s(%(params)s) +fastcc double %%ll_math_%(function)s(%(params)s) { + %%t = call ccc double %%%(function)s(%(params)s) ret double %%t } Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Wed Aug 3 01:43:25 2005 @@ -1,73 +1,101 @@ extdeclarations = """ ;ll_os.py -declare int %dup(int) -declare void %close(int) -declare int %open(sbyte*, int, int) -declare int %write(int, sbyte*, int) -declare int %read(int, sbyte*, int) -declare sbyte* %strncpy(sbyte*, sbyte*, int) -declare int %isatty(int) +declare ccc int %dup(int) +declare ccc void %close(int) +declare ccc int %open(sbyte*, int, int) +declare ccc int %write(int, sbyte*, int) +declare ccc int %read(int, sbyte*, int) +declare ccc sbyte* %strncpy(sbyte*, sbyte*, int) +declare ccc int %isatty(int) +declare ccc int %fstat(int, int*) """ extfunctions = {} extfunctions["%ll_os_dup"] = ((), """ -int %ll_os_dup(int %fd) { - %ret = call int %dup(int %fd) +fastcc int %ll_os_dup(int %fd) { + %ret = call ccc int %dup(int %fd) ret int %ret } """) extfunctions["%ll_os_close"] = ((), """ -void %ll_os_close(int %fd) { - call void %close(int %fd) +fastcc void %ll_os_close(int %fd) { + call ccc void %close(int %fd) ret void } """) extfunctions["%ll_os_open"] = (("%cast",), """ -int %ll_os_open(%structtype.rpy_string* %structstring, int %flag, int %mode) { - %dest = call sbyte* %cast(%structtype.rpy_string* %structstring) - %fd = call int %open(sbyte* %dest, int %flag, int %mode) +fastcc int %ll_os_open(%structtype.rpy_string* %structstring, int %flag, int %mode) { + %dest = call fastcc sbyte* %cast(%structtype.rpy_string* %structstring) + %fd = call ccc int %open(sbyte* %dest, int %flag, int %mode) ret int %fd } """) extfunctions["%ll_os_write"] = (("%cast",), """ -int %ll_os_write(int %fd, %structtype.rpy_string* %structstring) { +fastcc int %ll_os_write(int %fd, %structtype.rpy_string* %structstring) { %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr - %dest = call sbyte* %cast(%structtype.rpy_string* %structstring) - %byteswritten = call int %write(int %fd, sbyte* %dest, int %reallength) + %dest = call fastcc sbyte* %cast(%structtype.rpy_string* %structstring) + %byteswritten = call ccc int %write(int %fd, sbyte* %dest, int %reallength) ret int %byteswritten } """) extfunctions["%ll_read_into"] = ((), """ -int %ll_read_into(int %fd, %structtype.rpy_string* %structstring) { +fastcc int %ll_read_into(int %fd, %structtype.rpy_string* %structstring) { %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr %destptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 1 %dest = cast [0 x sbyte]* %destptr to sbyte* - %bytesread = call int %read(int %fd, sbyte* %dest, int %reallength) + %bytesread = call ccc int %read(int %fd, sbyte* %dest, int %reallength) ret int %bytesread } """) extfunctions["%ll_os_isatty"] = ((), """ -bool %ll_os_isatty(int %fd) { - %ret = call int %isatty(int %fd) +fastcc bool %ll_os_isatty(int %fd) { + %ret = call ccc int %isatty(int %fd) %ret.bool = cast int %ret to bool ret bool %ret.bool } """) +extfunctions["%ll_os_fstat"] = ((), """ +%structtype.tuple10* %ll_os_fstat(int %fd) { + %st = alloca int, uint 32 + %error = call ccc int %fstat(int %fd, int* %st) + ;TODO XXX if error: raise exception + ;%ret = %ll_stat_result__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed( + %ret = alloca %structtype.tuple10 ;ERROR + store int %s + ret %structtype.tuple10* %ret +} + +""") +#struct stat { +# 0 : dev_t res2 : st_dev; /* device */ +# 1 : ino_t res1 : st_ino; /* inode */ +# 2 : mode_t res0 : st_mode; /* protection */ +# 3 : nlink_t res3 : st_nlink; /* number of hard links */ +# 4 : uid_t res4 : st_uid; /* user ID of owner */ +# 5 : gid_t res5 : st_gid; /* group ID of owner */ +# 6 : dev_t : st_rdev; /* device type (if inode device) */ +# 7 : off_t res6 : st_size; /* total size, in bytes */ +# 8 : blksize_t : st_blksize; /* blocksize for filesystem I/O */ +# 9 : blkcnt_t : st_blocks; /* number of blocks allocated */ +# 10 : time_t res7 : st_atime; /* time of last access */ +# 11 : time_t res8 : st_mtime; /* time of last modification */ +# 12 : time_t res9 : st_ctime; /* time of last status change */ +#}; Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Wed Aug 3 01:43:25 2005 @@ -1,15 +1,15 @@ extdeclarations = ''' ;ll_time.py -declare int %time(int*) ;void* actually -declare int %clock() -declare void %sleep(int) +declare ccc int %time(int*) ;void* actually +declare ccc int %clock() +declare ccc void %sleep(int) ''' extfunctions = {} extfunctions["%ll_time_time"] = ((), """ -double %ll_time_time() { - %v0 = call int %time(int* null) +fastcc double %ll_time_time() { + %v0 = call ccc int %time(int* null) %v1 = cast int %v0 to double ret double %v1 } @@ -17,8 +17,8 @@ """) extfunctions["%ll_time_clock"] = ((), """ -double %ll_time_clock() { - %v0 = call int %clock() +fastcc double %ll_time_clock() { + %v0 = call ccc int %clock() %v1 = cast int %v0 to double ; XXX how to get at the proper division (or any other) constant per platform? %v2 = div double %v1, 1000000.0 ;CLOCKS_PER_SEC accrdoing to single unix spec @@ -28,9 +28,9 @@ """) extfunctions["%ll_time_sleep"] = ((), """ -void %ll_time_sleep(double %f) { +fastcc void %ll_time_sleep(double %f) { %i = cast double %f to int - call void %sleep(int %i) + call ccc void %sleep(int %i) ret void } Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Wed Aug 3 01:43:25 2005 @@ -3,16 +3,16 @@ extfunctions = {} extfunctions["%cast"] = ((), """ -sbyte* %cast(%structtype.rpy_string* %structstring) { +fastcc sbyte* %cast(%structtype.rpy_string* %structstring) { %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr %length = add int %reallength, 1 %ulength = cast int %length to uint - %dest = call sbyte* %gc_malloc_atomic(uint %ulength) + %dest = call fastcc sbyte* %gc_malloc_atomic(uint %ulength) %source1ptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 1 %source1 = cast [0 x sbyte]* %source1ptr to sbyte* - %dummy = call sbyte* %strncpy(sbyte* %dest, sbyte* %source1, int %reallength) + %dummy = call ccc sbyte* %strncpy(sbyte* %dest, sbyte* %source1, int %reallength) %zeropos1 = cast sbyte* %dest to int %zeropos2 = add int %zeropos1, %reallength Modified: pypy/dist/pypy/translator/llvm2/pyxwrapper.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/pyxwrapper.py (original) +++ pypy/dist/pypy/translator/llvm2/pyxwrapper.py Wed Aug 3 01:43:25 2005 @@ -16,7 +16,7 @@ funcgen.graph.returnblock.inputargs[0].concretetype] inputargtypes = [PRIMITIVES_TO_C[arg.concretetype] for arg in funcgen.graph.startblock.inputargs] - result = "%s %s(%s)" % (returntype, funcgen.ref.lstrip("%"), + result = "%s __entrypoint__%s(%s)" % (returntype, funcgen.ref.lstrip("%"), ", ".join(inputargtypes)) return result lines = [] @@ -24,14 +24,21 @@ inputargs = funcgen.db.repr_arg_multi(funcgen.graph.startblock.inputargs) inputargs = [x.strip("%") for x in inputargs] append("cdef extern " + c_declaration()) + append("cdef extern int __entrypoint__raised_LLVMException()") + append("") + append("class LLVMException(Exception):") + append(" pass") + append("") if use_boehm_gc: append("cdef extern int GC_get_heap_size()") append("") append("def GC_get_heap_size_wrapper():") append(" return GC_get_heap_size()") - append("") + append("") append("def %s_wrapper(%s):" % (funcgen.ref.strip("%"), ", ".join(inputargs))) - append(" return %s(%s)" % (funcgen.ref.strip("%"), ", ".join(inputargs))) + append(" result = __entrypoint__%s(%s)" % (funcgen.ref.strip("%"), ", ".join(inputargs))) + append(" if __entrypoint__raised_LLVMException(): #not caught by the LLVM code itself") + append(" raise LLVMException") + append(" return result") append("") targetpath.write("\n".join(lines)) - Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Wed Aug 3 01:43:25 2005 @@ -12,7 +12,7 @@ def getitem(l, i): #LookupError, KeyError if not isinstance(i, int): - raise LookupError + raise TypeError if i < 0: i = len(l) - i if i>= len(l): @@ -103,7 +103,6 @@ # assert f(0) == fn(0) def test_reraise1(): - py.test.skip("failing, uncaught exception causes exit!") def fn(n): lst = range(10) try: @@ -112,12 +111,12 @@ raise return 4 f = compile_function(fn, [int]) - assert f(-1) == fn(-1) + py.test.raises(Exception, "f(-1)") assert f( 0) == fn( 0) - assert f(10) == fn(10) + py.test.raises(Exception, "f(10)") def test_reraise2(): - py.test.skip("failing, uncaught exception causes exit!") + py.test.skip("PyPy interpreter not happy with this test") def fn(n): lst = range(10) try: @@ -126,9 +125,9 @@ raise e return 4 f = compile_function(fn, [int]) - assert f(-1) == fn(-1) + py.test.raises(Exception, "f(-1)") assert f( 0) == fn( 0) - assert f(10) == fn(10) + py.test.raises(Exception, "f(10)") def test_simple_exception(): def fn(n): @@ -194,7 +193,7 @@ assert f(1) == fn(1) assert f(2) == fn(2) assert f(3) == fn(3) - #py.test.raises(RuntimeError, "f(4)") #currently not raising a CPython exception + #py.test.raises(RuntimeError, "f(4)") #XXX would like to test: py.test.not_raises(....) assert f(5) == fn(5) assert f(6) == fn(6) assert f(13) == fn(13) Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Wed Aug 3 01:43:25 2005 @@ -97,28 +97,26 @@ def test_os_stat(): py.test.skip("ll_os_stat not implemented") filename = str(py.magic.autopath()) - def call_stat(): + def call_stat(n): st = os.stat(filename) - return st - f = compile_function(call_stat, []) - result = f() - assert result[0] == os.stat(filename)[0] - assert result[1] == os.stat(filename)[1] - assert result[2] == os.stat(filename)[2] + return st[n] + f = compile_function(call_stat, [int]) + assert f(0) == os.stat(filename)[0] + assert f(1) == os.stat(filename)[1] + assert f(2) == os.stat(filename)[2] def test_os_fstat(): py.test.skip("ll_os_fstat not implemented") filename = str(py.magic.autopath()) - def call_fstat(): + def call_fstat(n): fd = os.open(filename, os.O_RDONLY, 0777) st = os.fstat(fd) os.close(fd) - return st - f = compile_function(call_fstat, []) - result = f() - assert result[0] == os.stat(filename)[0] - assert result[1] == os.stat(filename)[1] - assert result[2] == os.stat(filename)[2] + return st[0] #XXX want to use 0 here! + f = compile_function(call_fstat, [int]) + assert f(0) == os.stat(filename)[0] + assert f(1) == os.stat(filename)[1] + assert f(2) == os.stat(filename)[2] def test_getcwd(): py.test.skip("ll_os_getcwd not implemented") From tismer at codespeak.net Wed Aug 3 06:23:58 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 3 Aug 2005 06:23:58 +0200 (CEST) Subject: [pypy-svn] r15531 - pypy/dist/pypy/objspace/std Message-ID: <20050803042358.1090B27B52@code1.codespeak.net> Author: tismer Date: Wed Aug 3 06:23:57 2005 New Revision: 15531 Modified: pypy/dist/pypy/objspace/std/longobject.py Log: small cosmetic changes Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Wed Aug 3 06:23:57 2005 @@ -590,7 +590,7 @@ 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(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int_Int' % opname], W_IntObject, W_IntObject, order=1) # unary ops for opname in ['neg', 'abs']: @@ -600,7 +600,7 @@ return %(opname)s__Long(space, w_long1) """ % {'opname': opname} - getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int' %opname], W_IntObject, order=1) + getattr(StdObjSpace.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): @@ -1597,7 +1597,7 @@ # than the sign bit). if intmask(x) < 0 and (sign > 0 or (x << 1) != 0): raise OverflowError - return intmask(x*sign) + return intmask(x * sign) def _hash(v): # This is designed so that Python ints and longs with the From tismer at codespeak.net Wed Aug 3 06:25:28 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 3 Aug 2005 06:25:28 +0200 (CEST) Subject: [pypy-svn] r15532 - pypy/dist/pypy/rpython Message-ID: <20050803042528.39BC327B52@code1.codespeak.net> Author: tismer Date: Wed Aug 3 06:25:26 2005 New Revision: 15532 Modified: pypy/dist/pypy/rpython/extfunctable.py Log: this is a crude hack to get windows to compile. PLEASE correct it. I just didn't bother. Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Wed Aug 3 06:25:26 2005 @@ -75,6 +75,10 @@ declare(os.dup , int , 'll_os/dup') declare(os.lseek , int , 'll_os/lseek') declare(os.isatty , bool , 'll_os/isatty') +try: + os.ftruncate # yes, this is a hack for windows, please make it better +except AttributeError: + os.ftruncate = lambda f: None declare(os.ftruncate, noneannotation, 'll_os/ftruncate') declare(os.fstat , statannotation, 'll_os/fstat') declare(os.stat , statannotation, 'll_os/stat') From tismer at codespeak.net Wed Aug 3 06:27:23 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 3 Aug 2005 06:27:23 +0200 (CEST) Subject: [pypy-svn] r15533 - pypy/dist/pypy/translator Message-ID: <20050803042723.B71D327B52@code1.codespeak.net> Author: tismer Date: Wed Aug 3 06:27:22 2005 New Revision: 15533 Modified: pypy/dist/pypy/translator/annrpython.py Log: added a debugging line with comment. When enabled, it breaks annotation on the first problem. I think we should have this as a translation option. Modified: pypy/dist/pypy/translator/annrpython.py ============================================================================== --- pypy/dist/pypy/translator/annrpython.py (original) +++ pypy/dist/pypy/translator/annrpython.py Wed Aug 3 06:27:22 2005 @@ -239,7 +239,8 @@ self.whereami((self.return_bindings[arg],None, None))) self.binding_caused_by[arg] = called_from - + # XXX make this line available as a debugging option + ##assert not (s_value.__class__ == annmodel.SomeObject and s_value.knowntype == object) ## debug #___ interface for annotator.bookkeeper _______ From tismer at codespeak.net Wed Aug 3 06:48:44 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 3 Aug 2005 06:48:44 +0200 (CEST) Subject: [pypy-svn] r15534 - in pypy/dist/pypy: interpreter module/marshal module/marshal/test objspace/std Message-ID: <20050803044844.0007827B52@code1.codespeak.net> Author: tismer Date: Wed Aug 3 06:48:41 2005 New Revision: 15534 Added: pypy/dist/pypy/module/marshal/ pypy/dist/pypy/module/marshal/__init__.py (contents, props changed) pypy/dist/pypy/module/marshal/interp_marshal.py (contents, props changed) pypy/dist/pypy/module/marshal/stackless_snippets.py (contents, props changed) pypy/dist/pypy/module/marshal/test/ pypy/dist/pypy/module/marshal/test/make_test_marshal.py (contents, props changed) pypy/dist/pypy/module/marshal/test/test_marshal.py (contents, props changed) pypy/dist/pypy/module/marshal/test/test_marshalimpl.py (contents, props changed) pypy/dist/pypy/objspace/std/marshal_impl.py (contents, props changed) Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/objspace/std/model.py pypy/dist/pypy/objspace/std/objspace.py Log: Hey, marshal is here! I added an interp-level marshal module. It is also enabled to do the basic marshalling and loading of .pyc files. This implementation is fairly fast. There is some performance to be gathered in the presence of files. Buffering has not been taken, yet. Hint: PyPy marshal does not use file descriptors, but file-like objects. For optimization, look for a seek method and redirect to the string marshaller. Make sure to seek back to the true end of the marshal. This is cheap, but make PyPy marshal much more versatile than CPython's. This implementation tries to be as compatible to builtin marshal as possible. At the time being, there is one problem: Recursion depth is not big enough to emulate CPython's nesting depth of 5000. I did a couple of aproaches to do it the stackless way. The snippets can be found in stackless_snippets, but nothing was pleasant enough, yet to make me incorporate it into the so far quite nice module. After all, every simpler effort brings me back to the way Stackless 3.1 implements things. I will finally implement an extension this way. Although I was not pleased with my temporary results, I have to say that RPython's object model is much nicer than that of the C language! The single inheritance is very, very powerful. I will use it to implement custom frame-like structures. I also agree with Armin's comment that such transformations should not be done by hand, but that we should find algorithms which generate this automatically. Besides that, I think it makes sense to explore these things, and marshal is a perfect example which is not too complicated, but reveals a number of non-trivial cases. Nevertheless, for complete CPython compatibility, it is necessary to limit object nesting to 5000, or CPython will crash. I do intend to back-translate the stackless version to CPython, in order to remove this arbitrary limitation. I'm also expecting new random arguments whioch will prevend this from getting into the core, as usual :-) Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Aug 3 06:48:41 2005 @@ -160,7 +160,7 @@ except AttributeError: pass - l = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', + l = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', 'marshal', '_sre'] if self.options.nofaking: @@ -198,7 +198,7 @@ self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin) for modname, mixedname in self.get_builtinmodule_list(): - if modname not in ('sys', '__builtin__', 'exceptions', 'marshal'): + if modname not in ('sys', '__builtin__', 'exceptions'):##!!, 'marshal'): self.setbuiltinmodule(modname, mixedname) # initialize with "bootstrap types" from objspace (e.g. w_None) Added: pypy/dist/pypy/module/marshal/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/marshal/__init__.py Wed Aug 3 06:48:41 2005 @@ -0,0 +1,18 @@ +# Package initialisation +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + """ + This module implements marshal at interpreter level. + """ + + appleveldefs = { + } + + interpleveldefs = { + 'dump' : 'interp_marshal.dump', + 'dumps' : 'interp_marshal.dumps', + 'load' : 'interp_marshal.load', + 'loads' : 'interp_marshal.loads', + 'version' : 'space.wrap(interp_marshal.Py_MARSHAL_VERSION)', + } Added: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Wed Aug 3 06:48:41 2005 @@ -0,0 +1,447 @@ +from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.error import OperationError +from pypy.rpython.rarithmetic import intmask +import sys + +# Py_MARSHAL_VERSION = 2 +# this is from Python 2.5 +# already implemented, but for compatibility, +# we default to version 1. Version 2 can be +# tested, anyway, by using the optional parameter. +# XXX auto-configure this by inspecting the +# Python version we emulate. How to do this? +Py_MARSHAL_VERSION = 1 + +def dump(space, w_data, w_f, w_version=Py_MARSHAL_VERSION): + writer = FileWriter(space, w_f) + # note: bound methods are currently not supported, + # so we have to pass the instance in, instead. + ##m = Marshaller(space, writer.write, space.int_w(w_version)) + m = Marshaller(space, writer, space.int_w(w_version)) + m.put_w_obj(w_data) + +def dumps(space, w_data, w_version=Py_MARSHAL_VERSION): + # using a list's append directly does not work, + # it leads to someobjectness. + writer = StringWriter() + m = Marshaller(space, writer, space.int_w(w_version)) + m.put_w_obj(w_data) + return space.wrap(writer.get_value()) + +def load(space, w_f): + reader = FileReader(space, w_f) + u = Unmarshaller(space, reader) + return u.get_w_obj(False) + +def loads(space, w_str): + reader = StringReader(space, w_str) + u = Unmarshaller(space, reader) + return u.get_w_obj(False) + + +class _BaseWriter(object): + pass + + +class _BaseReader(object): + def raise_eof(self): + space = self.space + raise OperationError(space.w_EOFError, space.wrap( + 'EOF read where object expected')) + + +class FileWriter(_BaseWriter): + def __init__(self, space, w_f): + self.space = space + try: + self.func = space.getattr(w_f, space.wrap('write')) + # XXX how to check if it is callable? + except OperationError: + raise OperationError(space.w_TypeError, space.wrap( + 'marshal.dump() 2nd arg must be file-like object')) + + def raise_eof(self): + space = self.space + raise OperationError(space.w_EOFError, space.wrap( + 'EOF read where object expected')) + + def write(self, data): + space = self.space + space.call_function(self.func, space.wrap(data)) + + +class FileReader(_BaseReader): + def __init__(self, space, w_f): + self.space = space + try: + self.func = space.getattr(w_f, space.wrap('read')) + # XXX how to check if it is callable? + except OperationError: + raise OperationError(space.w_TypeError, space.wrap( + 'marshal.load() arg must be file-like object')) + + def read(self, n): + space = self.space + w_ret = space.call_function(self.func, space.wrap(n)) + ret = space.str_w(w_ret) + if len(ret) != n: + self.raise_eof() + return ret + + +class StringWriter(_BaseWriter): + # actually we are writing to a stringlist + def __init__(self): + self.buflis = [] + + def write(self, data): + self.buflis.append(data) + + def get_value(self): + return ''.join(self.buflis) + + +class StringReader(_BaseReader): + def __init__(self, space, w_str): + self.space = space + try: + self.bufstr = space.str_w(w_str) + except OperationError: + raise OperationError(space.w_TypeError, space.wrap( + 'marshal.loads() arg must be string')) + self.bufpos = 0 + self.limit = len(self.bufstr) + + def read(self, n): + pos = self.bufpos + newpos = pos + n + if newpos > self.limit: + self.raise_eof() + self.bufpos = newpos + return self.bufstr[pos : newpos] + + +MAX_MARSHAL_DEPTH = 5000 + +# the above is unfortunately necessary because CPython +# relies on it without run-time checking. +# PyPy is currently in much bigger trouble, because the +# multimethod dispatches cause deeper stack nesting. + +# we try to do a true stack limit estimate, assuming that +# one applevel call costs at most APPLEVEL_STACK_COST +# nested calls. + +nesting_limit = sys.getrecursionlimit() +APPLEVEL_STACK_COST = 25 # XXX check if this is true + +CPYTHON_COMPATIBLE = True + +TEST_CONST = 10 + +class _Base(object): + def raise_exc(self, msg): + space = self.space + raise OperationError(space.w_ValueError, space.wrap(msg)) + +DONT_USE_MM_HACK = False + +class Marshaller(_Base): + # _annspecialcase_ = "specialize:ctr_location" # polymorphic + # does not work with subclassing + + def __init__(self, space, writer, version): + self.space = space + ## self.put = putfunc + self.writer = writer + self.version = version + # account for the applevel that we will call by one more. + self.nesting = ((space.getexecutioncontext().framestack.depth() + 1) + * APPLEVEL_STACK_COST + TEST_CONST) + self.cpy_nesting = 0 # contribution to compatibility + self.stringtable = {} + self.stackless = False + self._stack = None + self._iddict = {} + + ## currently we cannot use a put that is a bound method + ## from outside. Same holds for get. + def put(self, s): + self.writer.write(s) + + def atom(self, typecode): + assert type(typecode) is str and len(typecode) == 1 + self.put(typecode) + + def atom_int(self, typecode, x): + a = chr(x & 0xff) + x >>= 8 + b = chr(x & 0xff) + x >>= 8 + c = chr(x & 0xff) + x >>= 8 + d = chr(x & 0xff) + self.put(typecode + a + b + c + d) + + def atom_int64(self, typecode, x): + self.atom_int(typecode, x) + self.put_int(x>>32) + + def atom_str(self, typecode, x): + self.atom_int(typecode, len(x)) + self.put(x) + + def atom_strlist(self, typecode, tc2, x): + self.atom_int(typecode, len(x)) + for item in x: + if type(item) is not str: + self.raise_exc('object with wrong type in strlist') + self.atom_str(tc2, item) + + def start(self, typecode): + assert type(typecode) is str and len(typecode) == 1 + self.put(typecode) + + def put_short(self, x): + a = chr(x & 0xff) + x >>= 8 + b = chr(x & 0xff) + self.put(a + b) + + def put_int(self, x): + a = chr(x & 0xff) + x >>= 8 + b = chr(x & 0xff) + x >>= 8 + c = chr(x & 0xff) + x >>= 8 + d = chr(x & 0xff) + self.put(a + b + c + d) + + def put_pascal(self, x): + lng = len(x) + if lng > 255: + self.raise_exc('not a pascal string') + self.put(chr(lng)) + self.put(x) + + # HACK!ing a bit to loose some recursion depth and gain some speed. + # XXX it would be nicer to have a clean interface for this. + # remove this hack when we have optimization + # YYY we can drop the chain of mm dispatchers and save code if a method + # does not use NotImplemented at all. + def _get_mm_marshal(self, w_obj): + mm = getattr(w_obj, '__mm_marshal_w') + mm_func = mm.im_func + name = mm_func.func_code.co_names[0] + assert name.startswith('marshal_w_') + return mm_func.func_globals[name] + + def put_w_obj(self, w_obj): + self.nesting += 2 + do_nested = self.nesting < nesting_limit + if CPYTHON_COMPATIBLE: + self.cpy_nesting += 1 + do_nested = do_nested and self.cpy_nesting < MAX_MARSHAL_DEPTH + if do_nested: + if DONT_USE_MM_HACK: + self.nesting += 2 + self.space.marshal_w(w_obj, self) + self.nesting -= 2 + else: + self._get_mm_marshal(w_obj)(self.space, w_obj, self) + else: + self._run_stackless(w_obj) + self.nesting -= 2 + if CPYTHON_COMPATIBLE: + self.cpy_nesting -= 1 + + # this function is inlined below + def put_list_w(self, list_w, lng): + self.nesting += 1 + self.put_int(lng) + idx = 0 + while idx < lng: + self.put_w_obj(list_w[idx]) + idx += 1 + self.nesting -= 1 + + def put_list_w(self, list_w, lng): + if DONT_USE_MM_HACK: + # inlining makes no sense without the hack + self.nesting += 1 + self.put_int(lng) + idx = 0 + while idx < lng: + self.put_w_obj(list_w[idx]) + idx += 1 + self.nesting -= 1 + return + + # inlined version, two stack levels, only! + self.nesting += 2 + self.put_int(lng) + idx = 0 + space = self.space + do_nested = self.nesting < nesting_limit + if CPYTHON_COMPATIBLE: + self.cpy_nesting += 1 + do_nested = do_nested and self.cpy_nesting < MAX_MARSHAL_DEPTH + if do_nested: + while idx < lng: + w_obj = list_w[idx] + self._get_mm_marshal(w_obj)(space, w_obj, self) + idx += 1 + else: + while idx < lng: + w_obj = list_w[idx] + self._run_stackless(w_obj) + idx += 1 + self.nesting -= 2 + if CPYTHON_COMPATIBLE: + self.cpy_nesting -= 1 + + def _run_stackless(self, w_obj): + self.raise_exc('object too deeply nested to marshal') + + +def invalid_typecode(space, u, tc): + u.raise_exc('invalid typecode in unmarshal: %r' % tc) + +def register(codes, func): + """NOT_RPYTHON""" + for code in codes: + Unmarshaller._dispatch[ord(code)] = func + + +class Unmarshaller(_Base): + _dispatch = [invalid_typecode] * 256 + + def __init__(self, space, reader): + self.space = space + ## self.get = getfunc + self.reader = reader + # account for the applevel that we will call by one more. + self.nesting = ((space.getexecutioncontext().framestack.depth() + 1) + * APPLEVEL_STACK_COST) + self.stringtable_w = [] + + def get(self, n): + assert n >= 0 + return self.reader.read(n) + + def atom_str(self, typecode): + self.start(typecode) + lng = self.get_lng() + return self.get(lng) + + def atom_strlist(self, typecode, tc2): + self.start(typecode) + lng = self.get_lng() + res = [None] * lng + idx = 0 + while idx < lng: + res[idx] = self.atom_str(tc2) + idx += 1 + return res + + def start(self, typecode): + tc = self.get(1) + if tc != typecode: + self.raise_exc('invalid marshal data') + self.typecode = tc + + def get_short(self): + s = self.get(2) + a = ord(s[0]) + b = ord(s[1]) + x = a | (b << 8) + if x & 0x8000: + x = x - 0x10000 + return x + + def get_int(self): + s = self.get(4) + a = ord(s[0]) + b = ord(s[1]) + c = ord(s[2]) + d = ord(s[3]) + x = a | (b<<8) | (c<<16) | (d<<24) + return intmask(x) + + def get_lng(self): + s = self.get(4) + a = ord(s[0]) + b = ord(s[1]) + c = ord(s[2]) + d = ord(s[3]) + if d & 0x80: + self.raise_exc('bad marshal data') + x = a | (b<<8) | (c<<16) | (d<<24) + return x + + def get_pascal(self): + lng = ord(self.get(1)) + return self.get(lng) + + def get_str(self): + lng = self.get_lng() + return self.get(lng) + + # this function is inlined below + def get_list_w(self): + self.nesting += 1 + lng = self.get_lng() + res_w = [None] * lng + idx = 0 + while idx < lng: + res_w[idx] = self.get_w_obj(False) + idx += 1 + self.nesting -= 1 + return res_w + + def get_w_obj(self, allow_null): + self.nesting += 2 + if self.nesting < nesting_limit: + tc = self.get(1) + w_ret = self._dispatch[ord(tc)](self.space, self, tc) + if w_ret is None and not allow_null: + space = self.space + raise OperationError(space.w_TypeError, space.wrap( + 'NULL object in marshal data')) + else: + w_ret = self._run_stackless() + self.nesting -= 2 + return w_ret + + # inlined version to save a nesting level + def get_list_w(self): + self.nesting += 2 + lng = self.get_lng() + res_w = [None] * lng + idx = 0 + space = self.space + w_ret = space.w_None # something not None + if self.nesting < nesting_limit: + while idx < lng: + tc = self.get(1) + w_ret = self._dispatch[ord(tc)](space, self, tc) + if w_ret is None: + break + res_w[idx] = w_ret + idx += 1 + else: + while idx < lng: + w_ret = self._run_stackless() + if w_ret is None: + break + res_w[idx] = w_ret + idx += 1 + if w_ret is None: + raise OperationError(space.w_TypeError, space.wrap( + 'NULL object in marshal data')) + self.nesting -= 2 + return res_w + + def _run_stackless(self): + self.raise_exc('object too deeply nested to unmarshal') Added: pypy/dist/pypy/module/marshal/stackless_snippets.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/marshal/stackless_snippets.py Wed Aug 3 06:48:41 2005 @@ -0,0 +1,180 @@ +""" +This file contains various snippets of my attemts +to create a stackless marshal version. Finally, +I postponed this effort, because the recursive +solution gets quite far, already, and I wanted to +deliver a clean solution, after all. Explicit +stackless-ness is not very nice, after all. +""" + +""" + +Stackless extension: +-------------------- +I used marshal as an example of making recursive +algorithms iterative. At some point in the future, +we will try to automate such transformations. For the +time being, the approach used here is quite nice +and shows, how much superior RPython is over C. +Especially the simple inheritance makes writing +the necessary callbacks a pleasure. +I believe that the recursive version is always more +efficient (to be tested). The strategy used here is +to use recursion up to a small stack depth and to switch +to iteration at some point. + +""" + +class TupleEmitter(Emitter): + def init(self): + self.limit = len(self.w_obj.wrappeditems) + self.items_w = self.w_obj.wrappeditems + self.idx = 0 + def emit(self): + idx = self.idx + if idx < self.limit: + self.idx = idx + 1 + return self.items_w[idx] + + +class TupleCollector(Collector): + def init(self): + pass + def collect(self, w_obj): + idx = self.idx + if idx < self.limit: + self.idx = idx + 1 + self.items_w[idx] = w_obj + return True + return False + def fini(self): + return W_TupleObject(self.space, self.items_w) + + +class xxx(object): + def _run_stackless(self): + self.stackless = True + tc = self.get(1) + w_obj = unmarshal_dispatch[ord(tc)](self.space, self, tc) + while 1: + collector = self._stack + if not collector: + break + w_obj = emitter.emit() + if w_obj: + self.space.marshal_w(w_obj, self) + else: + emitter._teardown() + self.stackless = False + + def deferred_call(self, collector): + collector._setup() + +# stackless helper class + +class Collector(_Base): + def __init__(self, typecode, unmarshaller): + self.space = unmarshaller.space + self.typecode = typecode + + def _setup(self): + unmarshaller = self.unmarshaller + self.f_back = unmarshaller._stack + unmarshaller._stack = self + self.init() + + def collect(self, w_obj): + return False # to be overridden + + def _teardown(self): + self.unmarshaller._stack = self.f_back + return self.fini() + + +class ListCollector(Collector): + def __init__(self, space, typecode, count, finalizer): + Collector.__init__(self, space, typecode) + self.limit = count + self.finalizer = finalizer + self.items_w = [space.w_None] * count + self.idx = 0 + + def accumulate(self, w_data): + idx = self.idx + limit = self.limit + assert idx < limit + self.items_w[idx] = w_data + idx += 1 + self.idx = idx + return idx < limit + +class DictCollector(Collector): + def __init__(self, space, typecode, finalizer): + Collector.__init__(self, space, typecode) + self.finalizer = finalizer + self.items_w = [] + self.first = False + self.w_hold = None + + def accumulate(self, w_data): + first = not self.first + if w_data is None: + if not first: + self.raise_exc('bad marshal data') + return False + if first: + self.w_hold = w_data + else: + self.items_w.append( (self.w_hold, w_data) ) + self.first = first + return True + +class yyy(object): + def _run_stackless(self, w_obj): + self.stackless = True + self.space.marshal_w(w_obj, self) + while 1: + emitter = self._stack + if not emitter: + break + w_obj = emitter.emit() + if w_obj: + self.space.marshal_w(w_obj, self) + else: + emitter._teardown() + self.stackless = False + + def deferred_call(self, emitter): + emitter._setup() + +""" +Protocol: +Functions which write objects check the marshaller's stackless flag. +If set, they call the deferred_call() method with an instance of +an Emitter subclass. +""" + +class Emitter(_Base): + def __init__(self, w_obj, marshaller): + self.space = marshaller.space + self.marshaller = marshaller + self.w_obj = w_obj + + def _setup(self): + # from now on, we must keep track of recursive objects + marshaller = self.marshaller + iddict = marshaller._iddict + objid = id(self.w_obj) + if objid in iddict: + self.raise_exc('recursive objects cannot be marshalled') + self.f_back = marshaller._stack + marshaller._stack = self + iddict[objid] = 1 + + def _teardown(self): + del self.marshaller._iddict[id(self.w_obj)] + self.marshaller._stack = self.f_back + + def emit(self): + return None # to be overridden + Added: pypy/dist/pypy/module/marshal/test/make_test_marshal.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/marshal/test/make_test_marshal.py Wed Aug 3 06:48:41 2005 @@ -0,0 +1,76 @@ + +TESTCASES = """\ + None + False + True + StopIteration + Ellipsis + 42 + sys.maxint + -1.25 + -1.25 #2 + 2+5j + 2+5j #2 + 42L + -1234567890123456789012345678901234567890L + hello # not interned + "hello" + () + (1, 2) + [] + [3, 4] + {} + {5: 6, 7: 8} + func.func_code + scopefunc.func_code + u'hello' + set() + set([1, 2]) + frozenset() + frozenset([3, 4]) +""".strip().split('\n') + +def readable(s): + for c, repl in ( + ("'", '_quote_'), ('"', '_Quote_'), (':', '_colon_'), ('.', '_dot_'), + ('[', '_list_'), ('{', '_dict_'), ('-', '_minus_'), ('+', '_plus_'), + (',', '_comma_'), ('(', '_open_'), (')', '_close_') ): + s = s.replace(c, repl) + lis = list(s) + for i, c in enumerate(lis): + if c.isalnum() or c == '_': + continue + lis[i] = '_' + return ''.join(lis) + +print """class AppTestMarshal: +""" +for line in TESTCASES: + line = line.strip() + name = readable(line) + version = '' + extra = '' + if line.endswith('#2'): + version = ', 2' + extra = '; assert len(s) in (9, 17)' + src = '''\ + def test_%(name)s(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = %(line)s + print "case:", case + s = marshal.dumps(case%(version)s)%(extra)s + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case +''' % {'name': name, 'line': line, 'version' : version, 'extra': extra} + print src Added: pypy/dist/pypy/module/marshal/test/test_marshal.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/marshal/test/test_marshal.py Wed Aug 3 06:48:41 2005 @@ -0,0 +1,534 @@ +class AppTestMarshal: + + def test_None(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = None + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_False(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = False + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_True(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = True + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_StopIteration(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = StopIteration + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_Ellipsis(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = Ellipsis + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_42(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = 42 + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_sys_dot_maxint(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = sys.maxint + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__minus_1_dot_25(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = -1.25 + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__minus_1_dot_25__2(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = -1.25 #2 + print "case:", case + s = marshal.dumps(case, 2); assert len(s) in (9, 17) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_2_plus_5j(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = 2+5j + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_2_plus_5j__2(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = 2+5j #2 + print "case:", case + s = marshal.dumps(case, 2); assert len(s) in (9, 17) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_42L(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = 42L + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__minus_1234567890123456789012345678901234567890L(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = -1234567890123456789012345678901234567890L + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_hello_____not_interned(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = hello # not interned + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__Quote_hello_Quote_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = "hello" + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__open__close_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = () + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__open_1_comma__2_close_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = (1, 2) + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__list__(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = [] + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__list_3_comma__4_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = [3, 4] + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__dict__(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = {} + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test__dict_5_colon__6_comma__7_colon__8_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = {5: 6, 7: 8} + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_func_dot_func_code(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = func.func_code + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_scopefunc_dot_func_code(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = scopefunc.func_code + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_u_quote_hello_quote_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = u'hello' + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_set_open__close_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = set() + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_set_open__list_1_comma__2__close_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = set([1, 2]) + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_frozenset_open__close_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = frozenset() + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_frozenset_open__list_3_comma__4__close_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = frozenset([3, 4]) + print "case:", case + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + Added: pypy/dist/pypy/module/marshal/test/test_marshalimpl.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/marshal/test/test_marshalimpl.py Wed Aug 3 06:48:41 2005 @@ -0,0 +1,29 @@ +from pypy.module.marshal import interp_marshal +from pypy.interpreter.error import OperationError +import sys + +class TestInternalStuff: + def test_nesting(self): + space = self.space + app_cost = interp_marshal.APPLEVEL_STACK_COST + curdepth = space.getexecutioncontext().framestack.depth() + for do_hack in (False, True): + interp_marshal.DONT_USE_MM_HACK = not do_hack + if not do_hack: + interp_cost = 5 + else: + interp_cost = 2 + stacklimit = interp_marshal.nesting_limit - (curdepth + 1) * app_cost - interp_marshal.TEST_CONST + w_tup = space.newtuple([]) + tupdepth = 1 + for i in range(0, stacklimit - interp_cost-1, interp_cost): + w_tup = space.newtuple([w_tup]) + tupdepth += 1 + w_good = w_tup + s = interp_marshal.dumps(space, w_good, space.wrap(1)) + interp_marshal.loads(space, s) + w_bad = space.newtuple([w_tup]) + raises(OperationError, interp_marshal.dumps, space, w_bad, space.wrap(1)) + print 'max sys depth = %d, mm_hack = %r, marshal limit = %d' % ( + sys.getrecursionlimit(), do_hack, tupdepth) + Added: pypy/dist/pypy/objspace/std/marshal_impl.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/objspace/std/marshal_impl.py Wed Aug 3 06:48:41 2005 @@ -0,0 +1,481 @@ +# implementation of marshalling by multimethods + +""" +The idea is to have an effective but flexible +way to implement marshalling for the native types. + +The marshal_w operation is called with an object, +a callback and a state variable. +""" + +from pypy.interpreter.error import OperationError +from pypy.objspace.std.register_all import register_all +from pypy.rpython.rarithmetic import LONG_BIT +from pypy.objspace.std.floatobject import repr__Float as repr_float +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 + +from pypy.objspace.std.boolobject import W_BoolObject +from pypy.objspace.std.intobject import W_IntObject +from pypy.objspace.std.floatobject import W_FloatObject +from pypy.objspace.std.tupleobject import W_TupleObject +from pypy.objspace.std.listobject import W_ListObject +from pypy.objspace.std.dictobject import W_DictObject +from pypy.objspace.std.stringobject import W_StringObject +from pypy.objspace.std.typeobject import W_TypeObject +from pypy.objspace.std.longobject import W_LongObject +from pypy.objspace.std.noneobject import W_NoneObject +from pypy.objspace.std.unicodeobject import W_UnicodeObject + +import longobject +from pypy.objspace.std.strutil import string_to_float + +from pypy.module.marshal.interp_marshal import register + +TYPE_NULL = '0' +TYPE_NONE = 'N' +TYPE_FALSE = 'F' +TYPE_TRUE = 'T' +TYPE_STOPITER = 'S' +TYPE_ELLIPSIS = '.' +TYPE_INT = 'i' +TYPE_INT64 = 'I' +TYPE_FLOAT = 'f' +TYPE_BINARY_FLOAT = 'g' +TYPE_COMPLEX = 'x' +TYPE_BINARY_COMPLEX = 'y' +TYPE_LONG = 'l' +TYPE_STRING = 's' +TYPE_INTERNED = 't' +TYPE_STRINGREF = 'R' +TYPE_TUPLE = '(' +TYPE_LIST = '[' +TYPE_DICT = '{' +TYPE_CODE = 'c' +TYPE_UNICODE = 'u' +TYPE_UNKNOWN = '?' +TYPE_SET = '<' +TYPE_FROZENSET = '>' + +""" +simple approach: +a call to marshal_w has the following semantics: +marshal_w receives a marshaller object which contains +state and several methods. + + +atomic types including typecode: + +atom(tc) puts single typecode +atom_int(tc, int) puts code and int +atom_int64(tc, int64) puts code and int64 +atom_str(tc, str) puts code, len and string +atom_strlist(tc, strlist) puts code, len and list of strings + +building blocks for compound types: + +start(typecode) sets the type character +put(s) puts a string with fixed length +put_short(int) puts a short integer +put_int(int) puts an integer +put_pascal(s) puts a short string +put_w_obj(w_obj) puts a wrapped object +put_list_w(list_w, lng) puts a list of lng wrapped objects + +""" + +handled_by_any = [] + +def raise_exception(space, msg): + raise OperationError(space.w_ValueError, space.wrap(msg)) + +def marshal_w__None(space, w_none, m): + m.atom(TYPE_NONE) + +def unmarshal_None(space, u, tc): + return space.w_None +register(TYPE_NONE, unmarshal_None) + +def marshal_w__Bool(space, w_bool, m): + if w_bool.boolval: + m.atom(TYPE_TRUE) + else: + m.atom(TYPE_FALSE) + +def unmarshal_Bool(space, u, tc): + if tc == TYPE_TRUE: + return space.w_True + else: + return space.w_False +register(TYPE_TRUE + TYPE_FALSE, unmarshal_Bool) + +def marshal_w__Type(space, w_type, m): + if not space.is_w(w_type, space.w_StopIteration): + raise_exception(space, "unmarshallable object") + m.atom(TYPE_STOPITER) + +def unmarshal_Type(space, u, tc): + return space.w_StopIteration +register(TYPE_STOPITER, unmarshal_Type) + +# not directly supported: +def marshal_w_Ellipsis(space, w_ellipsis, m): + m.atom(TYPE_ELLIPSIS) + +StdObjSpace.MM.marshal_w.register(marshal_w_Ellipsis, Ellipsis) + +def unmarshal_Ellipsis(space, u, tc): + return space.w_Ellipsis +register(TYPE_ELLIPSIS, unmarshal_Ellipsis) + +def marshal_w__Int(space, w_int, m): + if LONG_BIT == 32: + m.atom_int(TYPE_INT, w_int.intval) + else: + y = w_int.intval >> 31 + if y and y != -1: + m.atom_int64(TYPE_INT64, w_int.intval) + else: + m.atom_int(TYPE_INT, w_int.intval) + +def unmarshal_Int(space, u, tc): + return W_IntObject(space, u.get_int()) +register(TYPE_INT, unmarshal_Int) + +def unmarshal_Int64(space, u, tc): + if LONG_BIT >= 64: + lo = u.get_int() & 0xffff + hi = u.get_int() + return W_IntObject(space, (hi << 32) or lo) + else: + # fall back to a long + # XXX at some point, we need to extend longobject + # by _PyLong_FromByteArray and _PyLong_AsByteArray. + # I will do that when implementing cPickle. + # for now, this rare case is solved the simple way. + lshift = longobject.lshift__Long_Long + longor = longobject.or__Long_Long + lo1 = space.newlong(u.get_short()) + lo2 = space.newlong(u.get_short()) + res = space.newlong(u.get_int()) + nbits = space.newlong(16) + res = lshift(space, res, nbits) + res = longor(space, res, lo2) + res = lshift(space, res, nbits) + res = longor(space, res, lo1) + return res +register(TYPE_INT64, unmarshal_Int64) + +# support for marshal version 2: +# we call back into the struct module. +# XXX struct should become interp-level. +# XXX we also should have an rtyper operation +# that allows to typecast between double and char{8} + +app = gateway.applevel(r''' + def float_to_str(fl): + import struct + return struct.pack(' 1: + m.start(TYPE_BINARY_FLOAT) + m.put(space.str_w(float_to_str(space, w_float))) + else: + m.start(TYPE_FLOAT) + m.put_pascal(space.str_w(repr_float(space, w_float))) + +def unmarshal_Float(space, u, tc): + if tc == TYPE_BINARY_FLOAT: + w_ret = str_to_float(space, space.wrap(u.get(8))) + fl = space.float_w(w_ret) + else: + fl = string_to_float(u.get_pascal()) + return W_FloatObject(space, fl) +register(TYPE_FLOAT + TYPE_BINARY_FLOAT, unmarshal_Float) + +# this is not a native type, yet, so we have to +# dispatch on it in ANY + +def marshal_w_Complex(space, w_complex, m): + w_real = space.getattr(w_complex, space.wrap('real')) + w_imag = space.getattr(w_complex, space.wrap('imag')) + if m.version > 1: + m.start(TYPE_BINARY_COMPLEX) + m.put(space.str_w(float_to_str(space, w_real))) + m.put(space.str_w(float_to_str(space, w_imag))) + else: + m.start(TYPE_COMPLEX) + m.put_pascal(space.str_w(repr_float(space, w_real))) + m.put_pascal(space.str_w(repr_float(space, w_imag))) + +handled_by_any.append( ('complex', marshal_w_Complex) ) + +def unmarshal_Complex(space, u, tc): + if tc == TYPE_BINARY_COMPLEX: + w_real = str_to_float(space, space.wrap(u.get(8))) + w_imag = str_to_float(space, space.wrap(u.get(8))) + else: + w_real = W_FloatObject(space, string_to_float(u.get_pascal())) + w_imag = W_FloatObject(space, string_to_float(u.get_pascal())) + w_t = space.builtin.get('complex') + return space.call_function(w_t, w_real, w_imag) +register(TYPE_COMPLEX + TYPE_BINARY_COMPLEX, unmarshal_Complex) + +def marshal_w__Long(space, w_long, m): + assert long_bits == 15, """if long_bits is not 15, + we need to write much more general code for marshal + that breaks things into pieces, or invent a new + typecode and have our own magic number for pickling""" + + m.start(TYPE_LONG) + lng = len(w_long.digits) + if w_long.sign < 0: + m.put_int(-lng) + else: + m.put_int(lng) + for digit in w_long.digits: + m.put_short(digit) + +def unmarshal_Long(space, u, tc): + lng = u.get_int() + if lng < 0: + sign = -1 + lng = -lng + elif lng > 0: + sign = 1 + else: + sign = 0 + digits = [0] * lng + i = 0 + while i < lng: + digit = u.get_short() + if digit < 0: + raise_exception(space, 'bad marshal data') + digits[i] = digit + i += 1 + return W_LongObject(space, digits, sign) +register(TYPE_LONG, unmarshal_Long) + +# XXX currently, intern() is at applevel, +# and there is no interface to get at the +# internal table. +# Move intern to interplevel and add a flag +# to strings. +def PySTRING_CHECK_INTERNED(w_str): + return False + +def marshal_w__String(space, w_str, m): + # using the fastest possible access method here + # that does not touch the internal representation, + # which might change (array of bytes?) + s = w_str.unwrap() + if m.version >= 1 and PySTRING_CHECK_INTERNED(w_str): + # we use a native rtyper stringdict for speed + idx = m.stringtable.get(s, -1) + if idx >= 0: + m.atom_int(TYPE_STRINGREF, idx) + else: + idx = len(m.stringtable) + m.stringtable[s] = idx + m.atom_str(TYPE_INTERNED, s) + else: + m.atom_str(TYPE_STRING, s) + +def unmarshal_String(space, u, tc): + return W_StringObject(space, u.get_str()) +register(TYPE_STRING, unmarshal_String) + +def unmarshal_interned(space, u, tc): + w_ret = W_StringObject(space, u.get_str()) + u.stringtable_w.append(w_ret) + w_intern = space.builtin.get('intern') + space.call_function(w_intern, w_ret) + return w_ret +register(TYPE_INTERNED, unmarshal_interned) + +def unmarshal_stringref(space, u, tc): + idx = u.get_int() + try: + return u.stringtable_w[idx] + except IndexError: + raise_exception(space, 'bad marshal data') +register(TYPE_STRINGREF, unmarshal_stringref) + +def marshal_w__Tuple(space, w_tuple, m): + m.start(TYPE_TUPLE) + m.put_list_w(w_tuple.wrappeditems, len(w_tuple.wrappeditems)) + +def unmarshal_Tuple(space, u, tc): + items_w = u.get_list_w() + return W_TupleObject(space, items_w) +register(TYPE_TUPLE, unmarshal_Tuple) + +def marshal_w__List(space, w_list, m): + m.start(TYPE_LIST) + n = w_list.ob_size + m.put_list_w(w_list.ob_item, w_list.ob_size) + +def unmarshal_List(space, u, tc): + items_w = u.get_list_w() + return W_ListObject(space, items_w) + +def finish_List(space, items_w, typecode): + return W_ListObject(space, items_w) +register(TYPE_LIST, unmarshal_List) + +def marshal_w__Dict(space, w_dict, m): + m.start(TYPE_DICT) + for entry in w_dict.data: + if entry.w_value is not None: + m.put_w_obj(entry.w_key) + m.put_w_obj(entry.w_value) + m.atom(TYPE_NULL) + +def unmarshal_Dict(space, u, tc): + items_w = [] + while 1: + w_key = u.get_w_obj(True) + if w_key is None: + break + w_value = u.get_w_obj(False) + items_w.append( (w_key, w_value) ) + return W_DictObject(space, items_w) +register(TYPE_DICT, unmarshal_Dict) + +def unmarshal_NULL(self, u, tc): + return None +register(TYPE_NULL, unmarshal_NULL) + +# this one is registered by hand: +def marshal_w_pycode(space, w_pycode, m): + m.start(TYPE_CODE) + # see pypy.interpreter.pycode for the layout + x = space.interpclass_w(w_pycode) + assert isinstance(x, PyCode) + m.put_int(x.co_argcount) + m.put_int(x.co_nlocals) + m.put_int(x.co_stacksize) + m.put_int(x.co_flags) + m.atom_str(TYPE_STRING, x.co_code) + m.start(TYPE_TUPLE) + m.put_list_w(x.co_consts_w, len(x.co_consts_w)) + m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_names) + m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_varnames) + m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_freevars) + m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_cellvars) + m.atom_str(TYPE_STRING, x.co_filename) + m.atom_str(TYPE_STRING, x.co_name) + m.put_int(x.co_firstlineno) + m.atom_str(TYPE_STRING, x.co_lnotab) + +StdObjSpace.MM.marshal_w.register(marshal_w_pycode, PyCode) + +def unmarshal_pycode(space, u, tc): + code = PyCode(space) + code.co_argcount = u.get_int() + code.co_nlocals = u.get_int() + code.co_stacksize = u.get_int() + code.co_flags = u.get_int() + code.co_code = u.atom_str(TYPE_STRING) + u.start(TYPE_TUPLE) + code.co_consts_w = u.get_list_w() + code.co_names = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) + code.co_varnames = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) + code.co_freevars = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) + code.co_cellvars = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) + code.co_filename = u.atom_str(TYPE_STRING) + code.co_name = u.atom_str(TYPE_STRING) + code.co_firstlineno = u.get_int() + code.co_lnotab = u.atom_str(TYPE_STRING) + return space.wrap(code) +register(TYPE_CODE, unmarshal_pycode) + +app = gateway.applevel(r''' + def PyUnicode_EncodeUTF8(data): + import _codecs + return _codecs.utf_8_encode(data)[0] + + def PyUnicode_DecodeUTF8(data): + import _codecs + return _codecs.utf_8_decode(data)[0] +''') + +PyUnicode_EncodeUTF8 = app.interphook('PyUnicode_EncodeUTF8') +PyUnicode_DecodeUTF8 = app.interphook('PyUnicode_DecodeUTF8') + +def marshal_w__Unicode(space, w_unicode, m): + s = space.str_w(PyUnicode_EncodeUTF8(space, w_unicode)) + m.atom_str(TYPE_UNICODE, s) + +def unmarshal_Unicode(space, u, tc): + return PyUnicode_DecodeUTF8(space, space.wrap(u.get_str())) +register(TYPE_UNICODE, unmarshal_Unicode) + +app = gateway.applevel(r''' + def set_to_list(theset): + return [item for item in theset] + + def list_to_set(datalist, frozen=False): + if frozen: + return frozenset(datalist) + return set(datalist) +''') + +set_to_list = app.interphook('set_to_list') +list_to_set = app.interphook('list_to_set') + +# not directly supported: +def marshal_w_set(space, w_set, m): + w_lis = set_to_list(space, w_set) + # cannot access this list directly, because it's + # type is not exactly known through applevel. + # otherwise, I would access ob_item and ob_size, directly. + lis_w = space.unpackiterable(w_lis) + m.start(TYPE_SET) + m.put_list_w(lis_w, len(lis_w)) + +handled_by_any.append( ('set', marshal_w_set) ) + +# not directly supported: +def marshal_w_frozenset(space, w_frozenset, m): + w_lis = set_to_list(space, w_frozenset) + lis_w = space.unpackiterable(w_lis) + m.start(TYPE_FROZENSET) + m.put_list_w(lis_w, len(lis_w)) + +handled_by_any.append( ('frozenset', marshal_w_frozenset) ) + +def unmarshal_set_frozenset(space, u, tc): + items_w = u.get_list_w() + if tc == TYPE_SET: + w_frozen = space.w_False + else: + w_frozen = space.w_True + w_lis = W_ListObject(space, items_w) + return list_to_set(space, w_lis, w_frozen) +register(TYPE_SET + TYPE_FROZENSET, unmarshal_set_frozenset) + +# dispatching for all not directly dispatched types +def marshal_w__ANY(space, w_obj, m): + w_type = space.type(w_obj) + for name, func in handled_by_any: + w_t = space.builtin.get(name) + if space.is_true(space.issubtype(w_type, w_t)): + func(space, w_obj, m) + break + else: + raise_exception(space, "unmarshallable object") + +register_all(vars()) Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Wed Aug 3 06:48:41 2005 @@ -5,7 +5,8 @@ from pypy.objspace.std.multimethod import MultiMethodTable, FailedToImplement from pypy.interpreter.baseobjspace import W_Root, ObjSpace - +import pypy.interpreter.pycode +import pypy.interpreter.special class StdTypeModel: @@ -52,6 +53,7 @@ from pypy.objspace.std import dictproxyobject from pypy.objspace.std import fake import pypy.objspace.std.default # register a few catch-all multimethods + import pypy.objspace.std.marshal_impl # install marshal multimethods # the set of implementation types self.typeorder = { @@ -71,6 +73,8 @@ iterobject.W_SeqIterObject: [], unicodeobject.W_UnicodeObject: [], dictproxyobject.W_DictProxyObject: [], + pypy.interpreter.pycode.PyCode: [], + pypy.interpreter.special.Ellipsis: [], } for type in self.typeorder: self.typeorder[type].append((type, None)) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Aug 3 06:48:41 2005 @@ -441,7 +441,7 @@ str_w = MultiMethod('str_w', 1, []) # returns an unwrapped string float_w = MultiMethod('float_w', 1, []) # returns an unwrapped float uint_w = MultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) - #marshal_w = MultiMethod('marshal_w', 1, [], extra_args=['foo']) + marshal_w = MultiMethod('marshal_w', 1, [], extra_args=['marshaller']) # add all regular multimethods here for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: From hpk at codespeak.net Wed Aug 3 09:54:23 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 3 Aug 2005 09:54:23 +0200 (CEST) Subject: [pypy-svn] r15538 - in pypy/dist/pypy: interpreter module/_sre module/marshal module/marshal/test objspace/std translator/goal Message-ID: <20050803075423.A743527B54@code1.codespeak.net> Author: hpk Date: Wed Aug 3 09:54:21 2005 New Revision: 15538 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/module/_sre/ (props changed) pypy/dist/pypy/module/marshal/ (props changed) pypy/dist/pypy/module/marshal/test/ (props changed) pypy/dist/pypy/module/marshal/test/test_marshal.py pypy/dist/pypy/objspace/std/model.py pypy/dist/pypy/translator/goal/targetpypymain.py Log: make the trunk translateable again + FIXEOL - marshal and _sre are now switched off by default and also don't get translated. You can use --usemodules=_sre or --usemodules=marshal or --usemodules=marshal,_sre for usage on pypy/cpython - don't import marshal multimethod in the objspace/std/model.py. We need to investigate what causes the 5 MM-related RTyper errors if you include it. - added some more comments and clarifications here and there Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Aug 3 09:54:21 2005 @@ -160,19 +160,26 @@ except AttributeError: pass - l = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', 'marshal', - '_sre'] + modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs'] if self.options.nofaking: - l.append('posix') - l.append('math') - l.append('time') - + modules.append('posix') + modules.append('math') + modules.append('time') + + # there also are the '_sre' and 'marshal' modules + # but those currently cause translation problems. You can + # enable them when running PyPy on top of CPython + # by e.g. specifying --usemodules=_sre,marshal for name in self.options.usemodules: - if name not in l: - l.append(name) + if name not in modules: + modules.append(name) - builtinmodule_list = [(x, None) for x in l] + # the returned builtinmodule_list contains tuples of + # names because some modules have a filesystem name + # that differs from the app-visible name (because you + # can specify implementation variants) + builtinmodule_list = [(x, None) for x in modules] if self.options.parser == "recparser": builtinmodule_list.append(('parser', 'recparser')) builtinmodule_list.append(('symbol', None)) Modified: pypy/dist/pypy/module/marshal/test/test_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/test/test_marshal.py (original) +++ pypy/dist/pypy/module/marshal/test/test_marshal.py Wed Aug 3 09:54:21 2005 @@ -1,4 +1,8 @@ + class AppTestMarshal: + def setup_class(cls): + from pypy.objspace.std import StdObjSpace + cls.space = StdObjSpace(usemodules=["marshal"]) def test_None(self): import sys Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Wed Aug 3 09:54:21 2005 @@ -53,7 +53,9 @@ from pypy.objspace.std import dictproxyobject from pypy.objspace.std import fake import pypy.objspace.std.default # register a few catch-all multimethods - import pypy.objspace.std.marshal_impl # install marshal multimethods + # XXX the following line causes 5 RTyper errors + # related to the marshal multimethod + #import pypy.objspace.std.marshal_impl # install marshal multimethods # the set of implementation types self.typeorder = { Modified: pypy/dist/pypy/translator/goal/targetpypymain.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypymain.py Wed Aug 3 09:54:21 2005 @@ -57,6 +57,7 @@ space = StdObjSpace(nofaking=True, compiler="pyparseapp", translating=True, + #usemodules=['marhsal', '_sre'], geninterp=False) # manually imports app_main.py From rxe at codespeak.net Wed Aug 3 10:36:46 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 10:36:46 +0200 (CEST) Subject: [pypy-svn] r15540 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050803083646.4187D27B62@code1.codespeak.net> Author: rxe Date: Wed Aug 3 10:36:44 2005 New Revision: 15540 Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: Add tests for overflows. Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Wed Aug 3 10:36:44 2005 @@ -276,6 +276,41 @@ f = compile_function(wrapper, [], view=True) assert f() +def test_int_overflow(): + py.test.skip("int_add_ovf operation missing (raises)") + fn = compile_function(snippet.add_func, [int]) + raises(OverflowError, fn, sys.maxint) + +def test_int_div_ovf_zer(): + py.test.skip("int_floordiv_ovf_zer operation missing (raises)") + fn = compile_function(snippet.div_func, [int]) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_mod_ovf_zer(): + py.test.skip("int_mod_ovf_zer operation missing (raises)") + fn = compile_function(snippet.mod_func, [int]) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_rshift_val(): + py.test.skip("int_rshift_val operation missing (raises)") + fn = compile_function(snippet.rshift_func, [int]) + raises(ValueError, fn, -1) + +def test_int_lshift_ovf_val(): + py.test.skip("int_lshift_ovf_val operation missing (raises)") + fn = compile_function(snippet.lshift_func, [int]) + raises(ValueError, fn, -1) + +def test_int_unary_ovf(): + py.test.skip("int_neg_ovf operation missing (raises)") + fn = compile_function(snippet.unary_func, [int]) + for i in range(-3,3): + assert fn(i) == (-(i), abs(i-1)) + raises (OverflowError, fn, -sys.maxint-1) + raises (OverflowError, fn, -sys.maxint) + def test_uint_arith(): py.test.skip("uint_floordiv_zer operation missing (raises)") def fn(i): From rxe at codespeak.net Wed Aug 3 10:37:07 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 10:37:07 +0200 (CEST) Subject: [pypy-svn] r15541 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050803083707.7331027B7A@code1.codespeak.net> Author: rxe Date: Wed Aug 3 10:37:06 2005 New Revision: 15541 Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Log: Comsmetic - reason for error was misleading. Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Wed Aug 3 10:37:06 2005 @@ -16,7 +16,7 @@ assert f() == 1 def test_simple_function_pointer(): - py.test.skip("function pointers not working yet") + py.test.skip("weird casting bug") def f1(x): return x + 1 def f2(x): From rxe at codespeak.net Wed Aug 3 10:40:18 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 10:40:18 +0200 (CEST) Subject: [pypy-svn] r15542 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050803084018.B772D27B62@code1.codespeak.net> Author: rxe Date: Wed Aug 3 10:40:17 2005 New Revision: 15542 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py Log: Add a whole lot of optimisatioms/transformations - taken from llvm's gccas. Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Wed Aug 3 10:40:17 2005 @@ -16,9 +16,129 @@ class CompileError(exceptions.Exception): pass -OPTIMIZATION_SWITCHES = "-simplifycfg -mem2reg -instcombine -dce -inline" +SOURCES = "time.ii ".split() + EXCEPTIONS_SWITCHES = "-enable-correct-eh-support" +OPTIMIZATION_SWITCHES = (" ".join([ + + # call %malloc -> malloc inst + "-raiseallocs", + + # clean up disgusting code + "-simplifycfg", + + # kill useless allocas + "-mem2reg", + + # optimize out global vars + "-globalopt", + + # remove unused fns and globs + "-globaldce", + + # interprocedural constant propagation + "-ipconstprop", + + # dead argument elimination + "-deadargelim", + + # clean up after + # (interprocedural constant propagation) & (dead argument elimination) + "-instcombine ", "-simplifycfg ", + + # clean up after + # (interprocedural constant propagation) & (dead argument elimination) + "-instcombine ", "-simplifycfg ", + + # remove dead EH info + "-prune-eh", + + # inline small functions + "-inline", + + # simplify well-known library calls + "-simplify-libcalls", + + # promote 'by reference' arguments to scalars + "-argpromotion", + + # recover type information + "--raise", + + # simplify cfg by copying code + "-tailduplicate", + + # merge & remove bacic blocks + "--simplifycfg", + + # break up aggregate allocas + "-scalarrepl", + + # combine silly seq's + "-instcombine", + + # propagate conditionals + "-condprop", + + # eliminate tail calls + '-tailcallelim', + + # merge & remove BBs + "-simplifycfg", + + # reassociate expressions + "-reassociate", + + # hoist loop invariants (LICM - Loop Invariant Code Motion) + "-licm", + + # clean up after LICM/reassoc + "-instcombine", + + # canonicalize indvars + "-indvars", + + # unroll small loops + "-loop-unroll", + + # clean up after the unroller + "-instcombine", + + # GVN for load instructions + "-load-vn", + + # remove common subexprs (Global Common Subexpression Elimination) + "-gcse", + + # constant prop with SCCP (Sparse Conditional Constant Propagation) + "-sccp", + + + # Run instcombine after redundancy elimination to exploit opportunities + # opened up by them + "-instcombine", + # propagate conditionals + "-condprop", + + # Delete dead stores + "-dse", + + # SSA based 'Aggressive DCE' + "-adce", + + # merge & remove BBs + "-simplifycfg", + + # eliminate dead types + "-deadtypeelim", + + # merge dup global constants + "-constmerge", + + ])) + + def compile_module(module, source_files, object_files, library_files): open("%s_setup.py" % module, "w").write(str(py.code.Source( ''' @@ -47,12 +167,12 @@ library_files = [] if use_boehm_gc: library_files.append('gc') - + if sys.maxint == 2147483647: #32 bit platform if optimize: - cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), + cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), "opt %s -f %s.bc -o %s_optimized.bc" % (OPTIMIZATION_SWITCHES, b, b), - "llc %s %s_optimized.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] + "llc --regalloc iterativescan %s %s_optimized.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] else: cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), "llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] From rxe at codespeak.net Wed Aug 3 10:59:10 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 10:59:10 +0200 (CEST) Subject: [pypy-svn] r15543 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050803085910.9A78F27B5E@code1.codespeak.net> Author: rxe Date: Wed Aug 3 10:59:08 2005 New Revision: 15543 Removed: pypy/dist/pypy/translator/llvm2/atomic.py Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/structnode.py Log: Rationalise atomic malloc a little. Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Wed Aug 3 10:59:08 2005 @@ -32,6 +32,15 @@ def setup(self): self.db.prepare_repr_arg_type(self.arraytype) + def is_atomic(self): + if isinstance(self.arraytype, lltype.Primitive): + return True + elif isinstance(self.arraytype, lltype.Ptr): + return False + else: + # XXX Recurse... + return False + # ______________________________________________________________________ # entry points from genllvm # @@ -47,7 +56,8 @@ fromtype = self.db.repr_arg_type(self.arraytype) varsize.write_constructor(codewriter, self.ref, self.constructor_decl, - fromtype) + fromtype, + atomicmalloc=self.is_atomic()) class VoidArrayTypeNode(LLVMNode): @@ -181,5 +191,4 @@ def constantvalue(self): return "{ int } {int %s}" % len(self.value.items) - Deleted: /pypy/dist/pypy/translator/llvm2/atomic.py ============================================================================== --- /pypy/dist/pypy/translator/llvm2/atomic.py Wed Aug 3 10:59:08 2005 +++ (empty file) @@ -1,20 +0,0 @@ -from pypy.translator.llvm2.log import log -from pypy.translator.llvm2.structnode import StructTypeNode -from pypy.translator.llvm2.arraynode import ArrayTypeNode -from pypy.rpython import lltype - -log = log.atomic - -def is_atomic(node): - # XXX is the below really right? - if isinstance(node, StructTypeNode): - fields = [getattr(node.struct, name) - for name in node.struct._names_without_voids()] - fields = [x for x in fields if isinstance(x, lltype.Ptr)] - if not fields: - return True #non-pointers only - return False #contains pointer(s) - elif isinstance(node, ArrayTypeNode): - return not isinstance(node.array.OF, lltype.Ptr) - log("unknown type %s, assuming non-atomic" % str(type(node))) - return False Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 3 10:59:08 2005 @@ -1,7 +1,6 @@ import py from pypy.objspace.flow.model import Constant from pypy.rpython import lltype -from pypy.translator.llvm2.atomic import is_atomic from pypy.translator.llvm2.log import log log = log.opwriter @@ -310,7 +309,7 @@ #XXX unclean node = self.db.obj2node[arg.value] type_ = node.ref - self.codewriter.malloc(targetvar, type_, atomic=is_atomic(node)) + self.codewriter.malloc(targetvar, type_, atomic=node.is_atomic()) def malloc_varsize(self, op): targetvar = self.db.repr_arg(op.result) @@ -325,7 +324,7 @@ from pypy.translator.llvm2.arraynode import VoidArrayTypeNode if isinstance(node, VoidArrayTypeNode): type_ = node.ref - self.codewriter.malloc(targetvar, type_, atomic=is_atomic(node)) + self.codewriter.malloc(targetvar, type_, atomic=True) return struct_type = node.ref Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Wed Aug 3 10:59:08 2005 @@ -18,18 +18,31 @@ def __str__(self): return "" %(self.ref,) + + def _fields(self): + return [getattr(self.struct, name) + for name in self.struct._names_without_voids()] def setup(self): # Recurse - for field in self.struct._flds.values(): + for field in self._fields(): self.db.prepare_repr_arg_type(field) + def is_atomic(self): + for f in self._fields(): + if isinstance(f, lltype.Ptr): + return False + + if not isinstance(f, lltype.Primitive): + # XXX Recurse + return False + + return True # ______________________________________________________________________ # main entry points from genllvm def writedatatypedecl(self, codewriter): - fields = [getattr(self.struct, name) - for name in self.struct._names_without_voids()] + fields = self._fields() codewriter.structdef(self.ref, self.db.repr_arg_type_multi(fields)) @@ -52,8 +65,6 @@ codewriter.declare(self.constructor_decl) def writeimpl(self, codewriter): - from pypy.translator.llvm2.atomic import is_atomic - log.writeimpl(self.ref) # build up a list of indices to get to the last @@ -70,7 +81,8 @@ # XXX write type info as a comment varsize.write_constructor(codewriter, self.ref, self.constructor_decl, arraytype, - indices_to_array) + indices_to_array, + atomicmalloc=self.is_atomic()) class StructNode(ConstantLLVMNode): """ A struct constant. Can simply contain From rxe at codespeak.net Wed Aug 3 11:00:51 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 11:00:51 +0200 (CEST) Subject: [pypy-svn] r15544 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050803090051.57E6C27B5E@code1.codespeak.net> Author: rxe Date: Wed Aug 3 11:00:49 2005 New Revision: 15544 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/ll_time.py Log: Generate the time code from genc's c code. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Wed Aug 3 11:00:49 2005 @@ -20,6 +20,18 @@ function_count = {} +# XXX Temp +raise_impl = """ +ccc void %RaiseSimpleException(int %t, sbyte* %ptErr) { +entry: + unwind + ret void +} +""" + +# XXX Temp +raise_decl = "declare ccc void %RaiseSimpleException(int, sbyte*)" + class GenLLVM(object): def __init__(self, translator, debug=False, embedexterns=True): @@ -77,6 +89,7 @@ nl(); comment("Function Prototypes") ; nl() if self.embedexterns: + codewriter.append(raise_decl) for extdecl in extdeclarations.split('\n'): codewriter.append(extdecl) @@ -112,6 +125,9 @@ codewriter.append(extfunc) depdone[dep] = True + if self.embedexterns: + codewriter.append(raise_impl) + #XXX use codewriter methods here decl = self.entrynode.getdecl() t = decl.split('%', 1) Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Wed Aug 3 11:00:49 2005 @@ -1,37 +1,86 @@ extdeclarations = ''' ;ll_time.py -declare ccc int %time(int*) ;void* actually + +%struct.timeval = type { int, int } +%struct.timezone = type { int, int } +%typedef.fd_set = type { [32 x int] } + +%.str_1 = internal constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] + +declare ccc double %floor(double) +declare ccc double %fmod(double, double) declare ccc int %clock() -declare ccc void %sleep(int) +declare ccc int %select(int, %typedef.fd_set*, %typedef.fd_set*, %typedef.fd_set*, %struct.timeval*) +declare ccc int %gettimeofday(%struct.timeval*, %struct.timeval*) +declare ccc int %time( int* ) ''' extfunctions = {} extfunctions["%ll_time_time"] = ((), """ + fastcc double %ll_time_time() { - %v0 = call ccc int %time(int* null) - %v1 = cast int %v0 to double - ret double %v1 + %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] + %secs = alloca int ; [#uses=2] + %tmp.0 = call int %gettimeofday( %struct.timeval* %t, %struct.timeval* null ) ; [#uses=1] + %tmp.1 = seteq int %tmp.0, 0 ; [#uses=2] + %tmp.2 = cast bool %tmp.1 to int ; [#uses=0] + br bool %tmp.1, label %then, label %endif + +then: ; preds = %entry + %tmp.3 = getelementptr %struct.timeval* %t, int 0, uint 0 ; [#uses=1] + %tmp.4 = load int* %tmp.3 ; [#uses=1] + %tmp.5 = cast int %tmp.4 to double ; [#uses=1] + %tmp.6 = getelementptr %struct.timeval* %t, int 0, uint 1 ; [#uses=1] + %tmp.7 = load int* %tmp.6 ; [#uses=1] + %tmp.8 = cast int %tmp.7 to double ; [#uses=1] + %tmp.9 = mul double %tmp.8, 1.000000e-06 ; [#uses=1] + %tmp.10 = add double %tmp.5, %tmp.9 ; [#uses=1] + ret double %tmp.10 + +endif: ; preds = %entry + %tmp.11 = call int %time( int* %secs ) ; [#uses=0] + %tmp.12 = load int* %secs ; [#uses=1] + %tmp.13 = cast int %tmp.12 to double ; [#uses=1] + ret double %tmp.13 } """) extfunctions["%ll_time_clock"] = ((), """ fastcc double %ll_time_clock() { - %v0 = call ccc int %clock() - %v1 = cast int %v0 to double - ; XXX how to get at the proper division (or any other) constant per platform? - %v2 = div double %v1, 1000000.0 ;CLOCKS_PER_SEC accrdoing to single unix spec - ret double %v2 +entry: + %tmp.0 = call int %clock( ) ; [#uses=1] + %tmp.1 = cast int %tmp.0 to double ; [#uses=1] + %tmp.2 = div double %tmp.1, 1.000000e+06 ; [#uses=1] + ret double %tmp.2 } - """) extfunctions["%ll_time_sleep"] = ((), """ -fastcc void %ll_time_sleep(double %f) { - %i = cast double %f to int - call ccc void %sleep(int %i) - ret void +fastcc void %ll_time_sleep(double %secs) { +entry: + %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] + %tmp.0 = call double %fmod( double %secs, double 1.000000e+00 ) ; [#uses=1] + %tmp.2 = call double %floor( double %secs ) ; [#uses=1] + %tmp.4 = getelementptr %struct.timeval* %t, int 0, uint 0 ; [#uses=1] + %tmp.6 = cast double %tmp.2 to int ; [#uses=1] + store int %tmp.6, int* %tmp.4 + %tmp.7 = getelementptr %struct.timeval* %t, int 0, uint 1 ; [#uses=1] + %tmp.9 = mul double %tmp.0, 1.000000e+06 ; [#uses=1] + %tmp.10 = cast double %tmp.9 to int ; [#uses=1] + store int %tmp.10, int* %tmp.7 + %tmp.11 = call int %select( int 0, %typedef.fd_set* null, %typedef.fd_set* null, %typedef.fd_set* null, %struct.timeval* %t ) ; [#uses=1] + %tmp.12 = setne int %tmp.11, 0 ; [#uses=2] + %tmp.13 = cast bool %tmp.12 to int ; [#uses=0] + br bool %tmp.12, label %then.1, label %return + +then.1: ; preds = %entry + call void %RaiseSimpleException( int 1, sbyte* getelementptr ([16 x sbyte]* %.str_1, int 0, int 0) ) + ret void + +return: ; preds = %entry + ret void } """) From rxe at codespeak.net Wed Aug 3 11:03:35 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 11:03:35 +0200 (CEST) Subject: [pypy-svn] r15545 - pypy/dist/pypy/translator/llvm2/demo Message-ID: <20050803090335.74DCD27B5E@code1.codespeak.net> Author: rxe Date: Wed Aug 3 11:03:33 2005 New Revision: 15545 Added: pypy/dist/pypy/translator/llvm2/demo/ pypy/dist/pypy/translator/llvm2/demo/bpnn.py pypy/dist/pypy/translator/llvm2/demo/richards.py Log: Add modified versions of bpnn and richard. Added: pypy/dist/pypy/translator/llvm2/demo/bpnn.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm2/demo/bpnn.py Wed Aug 3 11:03:33 2005 @@ -0,0 +1,271 @@ +#!/usr/bin/python +""" + Translator Demo + + Run this file -- over regular Python! -- to analyse and type-annotate + the functions and class defined in this module, starting from the + entry point function demo(). + + Requires Pygame. +""" +# Back-Propagation Neural Networks +# +# Written in Python. See http://www.python.org/ +# +# Neil Schemenauer +# +# Modifications to the original (Armin Rigo): +# * import random from PyPy's lib, which is Python 2.2's plain +# Python implementation +# * starts the Translator instead of the demo by default. + +import sys +import math +import time +import os, time + +# XXX the Translator needs the plain Python version of random.py: +from pypy.lib import random + +PRINT_IT = False + +random.seed(0) + +# calculate a random number where: a <= rand < b +def rand(a, b): + return (b-a)*random.random() + a + +# Make a matrix (we could use NumPy to speed this up) +def makeMatrix(I, J, fill=0.0): + m = [] + for i in range(I): + m.append([fill]*J) + return m + +class NN: + + def __init__(self, ni, nh, no): + # number of input, hidden, and output nodes + self.ni = ni + 1 # +1 for bias node + self.nh = nh + self.no = no + + # activations for nodes + self.ai = [1.0] * self.ni + self.ah = [1.0] * self.nh + self.ao = [1.0] * self.no + + # create weights + self.wi = makeMatrix(self.ni, self.nh) + self.wo = makeMatrix(self.nh, self.no) + # set them to random vaules + for i in range(self.ni): + for j in range(self.nh): + self.wi[i][j] = rand(-2.0, 2.0) + for j in range(self.nh): + for k in range(self.no): + self.wo[j][k] = rand(-2.0, 2.0) + + # last change in weights for momentum + self.ci = makeMatrix(self.ni, self.nh) + self.co = makeMatrix(self.nh, self.no) + + def update(self, inputs): + if len(inputs) != self.ni-1: + raise ValueError, 'wrong number of inputs' + + # input activations + i = 0 + while i < self.ni-1: + #self.ai[i] = 1.0/(1.0+math.exp(-inputs[i])) + self.ai[i] = inputs[i] + i += 1 + + # hidden activations + j = 0 + while j < self.nh: + sum = 0.0 + i = 0 + while i < self.ni: + sum = sum + self.ai[i] * self.wi[i][j] + i += 1 + self.ah[j] = 1.0/(1.0+math.exp(-sum)) + j += 1 + + # output activations + k = 0 + while k < self.no: + sum = 0.0 + for j in range(self.nh): + sum = sum + self.ah[j] * self.wo[j][k] + self.ao[k] = 1.0/(1.0+math.exp(-sum)) + k += 1 + + return self.ao[:] + + def backPropagate(self, targets, N, M): + if len(targets) != self.no: + raise ValueError, 'wrong number of target values' + + # calculate error terms for output + output_deltas = [0.0] * self.no + k = 0 + while k < self.no: + ao = self.ao[k] + output_deltas[k] = ao*(1-ao)*(targets[k]-ao) + k += 1 + + # calculate error terms for hidden + hidden_deltas = [0.0] * self.nh + j = 0 + while j < self.nh: + sum = 0.0 + k = 0 + while k < self.no: + sum = sum + output_deltas[k]*self.wo[j][k] + k += 1 + hidden_deltas[j] = self.ah[j]*(1-self.ah[j])*sum + j += 1 + + # update output weights + j = 0 + while j < self.nh: + k = 0 + while k < self.no: + change = output_deltas[k]*self.ah[j] + self.wo[j][k] = self.wo[j][k] + N*change + M*self.co[j][k] + self.co[j][k] = change + k += 1 + j += 1 + #print N*change, M*self.co[j][k] + + # update input weights + i = 0 + while i < self.ni: + j = 0 + while j < self.nh: + change = hidden_deltas[j]*self.ai[i] + self.wi[i][j] = self.wi[i][j] + N*change + M*self.ci[i][j] + self.ci[i][j] = change + j += 1 + i += 1 + + # calculate error + error = 0.0 + k = 0 + while k < len(targets): + error = error + 0.5*(targets[k]-self.ao[k])**2 + k += 1 + return error + + + def xtest(self, patterns): + for p in patterns: + #if PRINT_IT: + os.write(1, "[%d, %d] '->' " % (p[0][0], p[0][1])) + for ii in self.update(p[0]): + os.write(1, "%d " % int(ii * 1000)) + os.write(1, " \n") + + def weights(self): + if PRINT_IT: + print 'Input weights:' + for i in range(self.ni): + print self.wi[i] + print + print 'Output weights:' + for j in range(self.nh): + print self.wo[j] + + def train(self, patterns, iterations=2000, N=0.5, M=0.1): + # N: learning rate + # M: momentum factor + i = 0 + while i < iterations: + error = 0.0 + for p in patterns: + inputs = p[0] + targets = p[1] + self.update(inputs) + error = error + self.backPropagate(targets, N, M) + if PRINT_IT and i % 100 == 0: + print 'error %f' % error + i += 1 + +def demo(): + # Teach network XOR function + pat = [ + [[0,0], [0]], + [[0,1], [1]], + [[1,0], [1]], + [[1,1], [0]] + ] + + # create a network with two input, two hidden, and two output nodes + n = NN(2, 3, 1) + # train it with some patterns + n.train(pat, 2000) + # test it + n.xtest(pat) + return 0 +#_________________________________________________________ + +from pypy.translator.llvm2.genllvm import compile_function +import py + +def test_demo(): + py.log.setconsumer("genllvm", py.log.STDOUT) + py.log.setconsumer("genllvm database prepare", None) + f = compile_function(demo, []) + + print 'Running...' + T = time.time() + for i in range(10): + f() + t1 = time.time() - T + print "that took", t1 + + T = time.time() + for i in range(10): + demo() + t2 = time.time() - T + print "compared to", t2 + print "a speed-up of", t2/t1 + +def main(): + T = time.time() + os.write(1, 'Running...\n') + + for i in range(50): + demo() + + t1 = time.time() - T + os.write(1, 'That took... %d msecs \n' % int(t1 * 1000)) + return 0 + +if __name__ == "__main__": + from pypy.translator.llvm2.genllvm import compile_function + import py + + import sys + compile_llvm = True + if len(sys.argv) > 1: + if sys.argv[1] == "p": + main() + compile_llvm = False + elif sys.argv[1] == "c": + + from pypy.translator.translator import Translator + t = Translator(main) + a = t.annotate([]) + t.specialize() + f = t.ccompile() + f() + + compile_llvm = False + + if compile_llvm: + compile_function(main, []) + + # run with the following command + "llvmc -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc main_optimized.bc -o go" Added: pypy/dist/pypy/translator/llvm2/demo/richards.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm2/demo/richards.py Wed Aug 3 11:03:33 2005 @@ -0,0 +1,446 @@ + +# based on a Java version: +# Based on original version written in BCPL by Dr Martin Richards +# in 1981 at Cambridge University Computer Laboratory, England +# and a C++ version derived from a Smalltalk version written by +# L Peter Deutsch. +# Java version: Copyright (C) 1995 Sun Microsystems, Inc. +# Translation from C++, Mario Wolczko +# Outer loop added by Alex Jacoby + +# Task IDs +I_IDLE = 1 +I_WORK = 2 +I_HANDLERA = 3 +I_HANDLERB = 4 +I_DEVA = 5 +I_DEVB = 6 + +# Packet types +K_DEV = 1000 +K_WORK = 1001 + +# Packet + +BUFSIZE = 4 + +BUFSIZE_RANGE = range(BUFSIZE) + +class Packet: + def __init__(self,l,i,k): + self.link = l + self.ident = i + self.kind = k + self.datum = 0 + self.data = [0] * BUFSIZE + + def append_to(self,lst): + self.link = None + if lst is None: + return self + else: + p = lst + next = p.link + while next is not None: + p = next + next = p.link + p.link = self + return lst + +# Task Records + +class TaskRec: + pass + +class DeviceTaskRec(TaskRec): + def __init__(self): + self.pending = None + +class IdleTaskRec(TaskRec): + def __init__(self): + self.control = 1 + self.count = 10000 + +class HandlerTaskRec(TaskRec): + def __init__(self): + self.work_in = None + self.device_in = None + + def workInAdd(self,p): + self.work_in = p.append_to(self.work_in) + return self.work_in + + def deviceInAdd(self,p): + self.device_in = p.append_to(self.device_in) + return self.device_in + +class WorkerTaskRec(TaskRec): + def __init__(self): + self.destination = I_HANDLERA + self.count = 0 +# Task + +class TaskState: + def __init__(self): + self.packet_pending = True + self.task_waiting = False + self.task_holding = False + + def packetPending(self): + self.packet_pending = True + self.task_waiting = False + self.task_holding = False + return self + + def waiting(self): + self.packet_pending = False + self.task_waiting = True + self.task_holding = False + return self + + def running(self): + self.packet_pending = False + self.task_waiting = False + self.task_holding = False + return self + + def waitingWithPacket(self): + self.packet_pending = True + self.task_waiting = True + self.task_holding = False + return self + + def isPacketPending(self): + return self.packet_pending + + def isTaskWaiting(self): + return self.task_waiting + + def isTaskHolding(self): + return self.task_holding + + def isTaskHoldingOrWaiting(self): + return self.task_holding or (not self.packet_pending and self.task_waiting) + + def isWaitingWithPacket(self): + return self.packet_pending and self.task_waiting and not self.task_holding + + + + + +tracing = False +layout = 0 + +def trace(a): + global layout + layout -= 1 + if layout <= 0: + print + layout = 50 + print a, + + +TASKTABSIZE = 10 + +class TaskWorkArea: + def __init__(self): + self.taskTab = [None] * TASKTABSIZE + + self.taskList = None + + self.holdCount = 0 + self.qpktCount = 0 + +taskWorkArea = TaskWorkArea() + +class Task(TaskState): + + + def __init__(self,i,p,w,initialState,r): + self.link = taskWorkArea.taskList + self.ident = i + self.priority = p + self.input = w + + self.packet_pending = initialState.isPacketPending() + self.task_waiting = initialState.isTaskWaiting() + self.task_holding = initialState.isTaskHolding() + + self.handle = r + + taskWorkArea.taskList = self + taskWorkArea.taskTab[i] = self + + def fn(self,pkt,r): + raise NotImplementedError + + + def addPacket(self,p,old): + if self.input is None: + self.input = p + self.packet_pending = True + if self.priority > old.priority: + return self + else: + p.append_to(self.input) + return old + + + def runTask(self): + if self.isWaitingWithPacket(): + msg = self.input + self.input = msg.link + if self.input is None: + self.running() + else: + self.packetPending() + else: + msg = None + + return self.fn(msg,self.handle) + + + def waitTask(self): + self.task_waiting = True + return self + + + def hold(self): + taskWorkArea.holdCount += 1 + self.task_holding = True + return self.link + + + def release(self,i): + t = self.findtcb(i) + t.task_holding = False + if t.priority > self.priority: + return t + else: + return self + + + def qpkt(self,pkt): + t = self.findtcb(pkt.ident) + taskWorkArea.qpktCount += 1 + pkt.link = None + pkt.ident = self.ident + return t.addPacket(pkt,self) + + + def findtcb(self,id): + t = taskWorkArea.taskTab[id] + if t is None: + raise Exception("Bad task id %d" % id) + return t + + +# DeviceTask + + +class DeviceTask(Task): + def __init__(self,i,p,w,s,r): + Task.__init__(self,i,p,w,s,r) + + def fn(self,pkt,r): + d = r + assert isinstance(d, DeviceTaskRec) + if pkt is None: + pkt = d.pending + if pkt is None: + return self.waitTask() + else: + d.pending = None + return self.qpkt(pkt) + else: + d.pending = pkt + if tracing: trace(pkt.datum) + return self.hold() + + + +class HandlerTask(Task): + def __init__(self,i,p,w,s,r): + Task.__init__(self,i,p,w,s,r) + + def fn(self,pkt,r): + h = r + assert isinstance(h, HandlerTaskRec) + if pkt is not None: + if pkt.kind == K_WORK: + h.workInAdd(pkt) + else: + h.deviceInAdd(pkt) + work = h.work_in + if work is None: + return self.waitTask() + count = work.datum + if count >= BUFSIZE: + h.work_in = work.link + return self.qpkt(work) + + dev = h.device_in + if dev is None: + return self.waitTask() + + h.device_in = dev.link + dev.datum = work.data[count] + work.datum = count + 1 + return self.qpkt(dev) + +# IdleTask + + +class IdleTask(Task): + def __init__(self,i,p,w,s,r): + Task.__init__(self,i,0,None,s,r) + + def fn(self,pkt,r): + i = r + assert isinstance(i, IdleTaskRec) + i.count -= 1 + if i.count == 0: + return self.hold() + elif i.control & 1 == 0: + i.control /= 2 + return self.release(I_DEVA) + else: + i.control = i.control/2 ^ 0xd008 + return self.release(I_DEVB) + + +# WorkTask + + +A = ord('A') + +class WorkTask(Task): + def __init__(self,i,p,w,s,r): + Task.__init__(self,i,p,w,s,r) + + def fn(self,pkt,r): + w = r + assert isinstance(w, WorkerTaskRec) + if pkt is None: + return self.waitTask() + + if w.destination == I_HANDLERA: + dest = I_HANDLERB + else: + dest = I_HANDLERA + + w.destination = dest + pkt.ident = dest + pkt.datum = 0 + + for i in BUFSIZE_RANGE: # xrange(BUFSIZE) + w.count += 1 + if w.count > 26: + w.count = 1 + pkt.data[i] = A + w.count - 1 + + return self.qpkt(pkt) + +import time + + + +def schedule(): + t = taskWorkArea.taskList + while t is not None: + pkt = None + + if tracing: + print "tcb =",t.ident + + if t.isTaskHoldingOrWaiting(): + t = t.link + else: + if tracing: trace(chr(ord("0")+t.ident)) + t = t.runTask() + +class Richards: + + iterations = 25 + + def run(self): + for i in xrange(self.iterations): + taskWorkArea.holdCount = 0 + taskWorkArea.qpktCount = 0 + + IdleTask(I_IDLE, 1, 10000, TaskState().running(), IdleTaskRec()) + + wkq = Packet(None, 0, K_WORK) + wkq = Packet(wkq , 0, K_WORK) + WorkTask(I_WORK, 1000, wkq, TaskState().waitingWithPacket(), WorkerTaskRec()) + + wkq = Packet(None, I_DEVA, K_DEV) + wkq = Packet(wkq , I_DEVA, K_DEV) + wkq = Packet(wkq , I_DEVA, K_DEV) + HandlerTask(I_HANDLERA, 2000, wkq, TaskState().waitingWithPacket(), HandlerTaskRec()) + + wkq = Packet(None, I_DEVB, K_DEV) + wkq = Packet(wkq , I_DEVB, K_DEV) + wkq = Packet(wkq , I_DEVB, K_DEV) + HandlerTask(I_HANDLERB, 3000, wkq, TaskState().waitingWithPacket(), HandlerTaskRec()) + + wkq = None; + DeviceTask(I_DEVA, 4000, wkq, TaskState().waiting(), DeviceTaskRec()); + DeviceTask(I_DEVB, 5000, wkq, TaskState().waiting(), DeviceTaskRec()); + + schedule() + + if taskWorkArea.holdCount == 9297 and taskWorkArea.qpktCount == 23246: + pass + else: + return False + + return True + +def entry_point(): + r = Richards() + startTime = time.time() + result = r.run() + endTime = time.time() + return result, startTime, endTime + +def main(): + import os + os.write(1, "Richards benchmark (Python) starting... \n") + result, startTime, endTime = entry_point() + if not result: + os.write(1, "Incorrect results!\n") + return 1 + os.write(1, "finished.\n") + total_s = endTime - startTime + os.write(1, "\nTotal time for %d iterations: %d msecs\n" %(Richards.iterations, int(1000 * total_s))) + os.write(1, "Average time for iterations: %d ms\n" % (int(total_s * 1000)/Richards.iterations)) + return 0 + +if __name__ == "__main__": + from pypy.translator.llvm2.genllvm import compile_function + import py + + import sys + compile_llvm = True + if len(sys.argv) > 1: + if sys.argv[1] == "p": + main() + compile_llvm = False + elif sys.argv[1] == "c": + + from pypy.translator.translator import Translator + t = Translator(main) + a = t.annotate([]) + t.specialize() + f = t.ccompile() + f() + + compile_llvm = False + + if compile_llvm: + compile_function(main, []) + + # run with the following command + "llvmc -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc main_optimized.bc -o go" From ericvrp at codespeak.net Wed Aug 3 11:20:26 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 11:20:26 +0200 (CEST) Subject: [pypy-svn] r15546 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050803092026.886F727B76@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 11:20:25 2005 New Revision: 15546 Removed: pypy/dist/pypy/translator/llvm2/pickleformat.txt Log: This was an idea of cfbolz and hpk and was not used in the end. It was ment to be an alternative to PBC's that caused some problems during the Goteborg sprint. PBC now work fine. Deleted: /pypy/dist/pypy/translator/llvm2/pickleformat.txt ============================================================================== --- /pypy/dist/pypy/translator/llvm2/pickleformat.txt Wed Aug 3 11:20:25 2005 +++ (empty file) @@ -1,61 +0,0 @@ -x = ptr({6, 7}) -a = {4, 5, x} -b = {8, 9, x} -c = {a,b} - -GET_Tx can be either LOAD_Tx or REF_Tx_index - -LOAD_T1 4 5 (LOAD_T0 6 7) # REF_T1_0 -LOAD_T1 8 9 REF_T0_0 # REF_T1_1 -LOAD_T2 REF_T1_0 REF_T1_1 # REF_T2_0 - -T0 = GcStruct(...) - -T0TBL = Array(Ptr(T0)) -T1TBL = Array(Ptr(T1)) - -ALL_LISTS = GcStruct('all_lists', - ('t0s', Ptr(T0TBL)), - ('t1s', Ptr(T1TBL)), - ('count0', Signed), - ('count1', Signed)) - -def ll_dispatch(fd): - while 1: - instr = ll_read_instr(fd) - if iseof(instr): - break - assert isload(instr) - typeindex = getindex(instr) - ll_get = ll_GET_FUNCTION_LIST[typeindex] - ll_get(fd, instr, all_lists) - -def ll_GET_T0(fd, instr, all_lists): - if isload(instr): - val1 = ll_read_int(fd) - val2 = ll_read_int(fd) - x = malloc(T0) - x.val1 = val1 - x.val2 = val2 - all_lists.t0s[all_lists.count0] = x - all_lists.count0 += 1 - return x - else: - if is_zero_ptr(instr): - return nullptr(T0) - return all_lists.t0s[getindex(instr)] - -def ll_GET_T1(fd, instr, all_lists): - if isload(instr): - val1 = ll_read_int(fd) - val2 = ll_read_int(fd) - instr = ll_read_instr(fd) - val3 = ll_get_T0(fd, instr) - x = malloc(T1) - x.val1 = val1 - x.val2 = val2 - x.val3 = val3 - T1.append(x) - return x - else: - return T1[getindex(instr)] From nik at codespeak.net Wed Aug 3 11:24:10 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 3 Aug 2005 11:24:10 +0200 (CEST) Subject: [pypy-svn] r15547 - in pypy/dist: lib-python/modified-2.4.1 pypy/module/_sre Message-ID: <20050803092410.327EB27B76@code1.codespeak.net> Author: nik Date: Wed Aug 3 11:24:08 2005 New Revision: 15547 Modified: pypy/dist/lib-python/modified-2.4.1/sre_constants.py pypy/dist/pypy/module/_sre/app_sre.py Log: put hack for _sre faking on 2.3 back into place. sorry for breaking translation with the integration yesterday, didn't think an app-level MixedModule could affect it. Modified: pypy/dist/lib-python/modified-2.4.1/sre_constants.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/sre_constants.py (original) +++ pypy/dist/lib-python/modified-2.4.1/sre_constants.py Wed Aug 3 11:24:08 2005 @@ -129,13 +129,10 @@ # PyPy hack to make the sre_*.py files from 2.4.1 work on the _sre # engine of 2.3. -# XXX This hack doesn't work anymore because it creates a circular import -# problem. Maybe think about a different hack, otherwise we're not able to run -# faked _sre on CPython 2.3. -#import _sre -#if _sre.MAGIC < 20031017: -# OPCODES.remove(GROUPREF_EXISTS) -#del _sre +import _sre +if _sre.MAGIC < 20031017: + OPCODES.remove(GROUPREF_EXISTS) +del _sre ATCODES = [ AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY, Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Wed Aug 3 11:24:08 2005 @@ -8,8 +8,11 @@ """ import array, operator, sys -import sre_constants -from sre_constants import ATCODES, OPCODES, CHCODES, MAXREPEAT +# XXX Avoiding sre_constants import on module level to cater for a hack in +# sre_constants concerned with _sre faking on 2.3. Fix this when _sre faking is +# not an issue anymore. +#import sre_constants +#from sre_constants import ATCODES, OPCODES, CHCODES, MAXREPEAT # Identifying as _sre from Python 2.3 or 2.4 if sys.version_info[:2] == (2, 4): @@ -40,6 +43,7 @@ return SRE_Pattern(pattern, flags, code, groups, groupindex, indexgroup) def getlower(char_ord, flags): + import sre_constants if (char_ord < 128) or (flags & sre_constants.SRE_FLAG_UNICODE) \ or (flags & sre_constants.SRE_FLAG_LOCALE and char_ord < 256): return ord(unichr(char_ord).lower()) @@ -365,6 +369,7 @@ return has_matched def search(self, pattern_codes): + from sre_constants import OPCODES if pattern_codes[0] == OPCODES["info"]: pattern_codes = pattern_codes[pattern_codes[1] + 1:] # XXX USE_FAST_SEARCH optimizations missing here @@ -484,6 +489,8 @@ raise NotImplementedError() def build_dispatch_table(cls, code_dict, method_prefix): + if cls.DISPATCH_TABLE is not None: + return table = {} for key, value in code_dict.items(): if hasattr(cls, "%s%s" % (method_prefix, key)): @@ -497,10 +504,15 @@ def __init__(self): self.executing_contexts = {} + from sre_constants import ATCODES, OPCODES, CHCODES + _OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") + _AtcodeDispatcher.build_dispatch_table(ATCODES, "") + _ChcodeDispatcher.build_dispatch_table(CHCODES, "") + _CharsetDispatcher.build_dispatch_table(OPCODES, "set_") self.at_dispatcher = _AtcodeDispatcher() self.ch_dispatcher = _ChcodeDispatcher() self.set_dispatcher = _CharsetDispatcher() - + def match(self, context): """Returns True if the current context matches, False if it doesn't and None if matching is not finished, ie must be resumed after child @@ -694,6 +706,7 @@ # this operator only works if the repeated item is exactly one character # wide, and we're not already collecting backtracking points. # <1=min> <2=max> item tail + from sre_constants import OPCODES mincount = ctx.peek_code(2) maxcount = ctx.peek_code(3) #self._log(ctx, "REPEAT_ONE", mincount, maxcount) @@ -735,6 +748,7 @@ def op_min_repeat_one(self, ctx): # match repeated sequence (minimizing) # <1=min> <2=max> item tail + from sre_constants import OPCODES, MAXREPEAT mincount = ctx.peek_code(2) maxcount = ctx.peek_code(3) #self._log(ctx, "MIN_REPEAT_ONE", mincount, maxcount) @@ -793,6 +807,7 @@ def op_max_until(self, ctx): # maximizing repeat # <1=min> <2=max> item tail + from sre_constants import MAXREPEAT repeat = ctx.state.repeat if repeat is None: raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") @@ -844,6 +859,7 @@ def op_min_until(self, ctx): # minimizing repeat # <1=min> <2=max> item tail + from sre_constants import MAXREPEAT repeat = ctx.state.repeat if repeat is None: raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") @@ -975,6 +991,7 @@ """Returns the number of repetitions of a single item, starting from the current string position. The code pointer is expected to point to a REPEAT_ONE operation (with the repeated 4 ahead).""" + from sre_constants import MAXREPEAT count = 0 real_maxcount = ctx.state.end - ctx.string_position if maxcount < real_maxcount and maxcount != MAXREPEAT: @@ -1004,8 +1021,6 @@ _log("|%s|%s|%s %s" % (context.pattern_codes, context.string_position, opname, arg_string)) -_OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") - class _CharsetDispatcher(_Dispatcher): @@ -1076,9 +1091,6 @@ return False -_CharsetDispatcher.build_dispatch_table(OPCODES, "set_") - - class _AtcodeDispatcher(_Dispatcher): def at_beginning(self, ctx): @@ -1107,8 +1119,6 @@ def unknown(self, ctx): return False -_AtcodeDispatcher.build_dispatch_table(ATCODES, "") - class _ChcodeDispatcher(_Dispatcher): @@ -1151,8 +1161,6 @@ def unknown(self, ctx): return False -_ChcodeDispatcher.build_dispatch_table(CHCODES, "") - _ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, From ericvrp at codespeak.net Wed Aug 3 12:09:36 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 12:09:36 +0200 (CEST) Subject: [pypy-svn] r15548 - pypy/dist/pypy/translator/llvm2/demo Message-ID: <20050803100936.605C827B59@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 12:09:35 2005 New Revision: 15548 Added: pypy/dist/pypy/translator/llvm2/demo/autopath.py (contents, props changed) Modified: pypy/dist/pypy/translator/llvm2/demo/bpnn.py Log: made it runnable Added: pypy/dist/pypy/translator/llvm2/demo/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm2/demo/autopath.py Wed Aug 3 12:09:35 2005 @@ -0,0 +1,120 @@ +""" +self cloning, automatic path configuration + +copy this into any subdirectory of pypy from which scripts need +to be run, typically all of the test subdirs. +The idea is that any such script simply issues + + import autopath + +and this will make sure that the parent directory containing "pypy" +is in sys.path. + +If you modify the master "autopath.py" version (in pypy/tool/autopath.py) +you can directly run it which will copy itself on all autopath.py files +it finds under the pypy root directory. + +This module always provides these attributes: + + pypydir pypy root directory path + this_dir directory where this autopath.py resides + +""" + + +def __dirinfo(part): + """ return (partdir, this_dir) and insert parent of partdir + into sys.path. If the parent directories don't have the part + an EnvironmentError is raised.""" + + import sys, os + try: + head = this_dir = os.path.realpath(os.path.dirname(__file__)) + except NameError: + head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) + + while head: + partdir = head + head, tail = os.path.split(head) + if tail == part: + break + else: + raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir) + + checkpaths = sys.path[:] + pypy_root = os.path.join(head, '') + + while checkpaths: + orig = checkpaths.pop() + fullorig = os.path.join(os.path.realpath(orig), '') + if fullorig.startswith(pypy_root): + if os.path.exists(os.path.join(fullorig, '__init__.py')): + sys.path.remove(orig) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) + + munged = {} + for name, mod in sys.modules.items(): + fn = getattr(mod, '__file__', None) + if '.' in name or not isinstance(fn, str): + continue + newname = os.path.splitext(os.path.basename(fn))[0] + if not newname.startswith(part + '.'): + continue + path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') + if path.startswith(pypy_root) and newname != part: + modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) + if newname != '__init__': + modpaths.append(newname) + modpath = '.'.join(modpaths) + if modpath not in sys.modules: + munged[modpath] = mod + + for name, mod in munged.iteritems(): + if name not in sys.modules: + sys.modules[name] = mod + if '.' in name: + prename = name[:name.rfind('.')] + postname = name[len(prename)+1:] + if prename not in sys.modules: + __import__(prename) + if not hasattr(sys.modules[prename], postname): + setattr(sys.modules[prename], postname, mod) + + return partdir, this_dir + +def __clone(): + """ clone master version of autopath.py into all subdirs """ + from os.path import join, walk + if not this_dir.endswith(join('pypy','tool')): + raise EnvironmentError("can only clone master version " + "'%s'" % join(pypydir, 'tool',_myname)) + + + def sync_walker(arg, dirname, fnames): + if _myname in fnames: + fn = join(dirname, _myname) + f = open(fn, 'rwb+') + try: + if f.read() == arg: + print "checkok", fn + else: + print "syncing", fn + f = open(fn, 'w') + f.write(arg) + finally: + f.close() + s = open(join(pypydir, 'tool', _myname), 'rb').read() + walk(pypydir, sync_walker, s) + +_myname = 'autopath.py' + +# set guaranteed attributes + +pypydir, this_dir = __dirinfo('pypy') + +if __name__ == '__main__': + __clone() Modified: pypy/dist/pypy/translator/llvm2/demo/bpnn.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/bpnn.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/bpnn.py Wed Aug 3 12:09:35 2005 @@ -25,6 +25,7 @@ import os, time # XXX the Translator needs the plain Python version of random.py: +import autopath from pypy.lib import random PRINT_IT = False @@ -220,13 +221,13 @@ print 'Running...' T = time.time() - for i in range(10): + for i in range(30): f() t1 = time.time() - T print "that took", t1 T = time.time() - for i in range(10): + for i in range(30): demo() t2 = time.time() - T print "compared to", t2 @@ -267,5 +268,17 @@ if compile_llvm: compile_function(main, []) + # generate runnable bytecode with the following command + os.write(1, 'Generating standalone LLVM bytecode:\n') + cmd = "llvmc -O5 -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc /tmp/usession-current/main_optimized.bc -o bpnn" + os.write(1, cmd + '\n') + os.system(cmd) + # run with the following command - "llvmc -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc main_optimized.bc -o go" + os.write(1, 'Running standalone LLVM bytecode:\n') + cmd = "./bpnn" + os.write(1, cmd + '\n') + os.system(cmd) + + os.write(1, 'Running on top of CPython:\n') + main() From lac at codespeak.net Wed Aug 3 13:18:14 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 3 Aug 2005 13:18:14 +0200 (CEST) Subject: [pypy-svn] r15549 - pypy/dist Message-ID: <20050803111814.9B0E727B6A@code1.codespeak.net> Author: lac Date: Wed Aug 3 13:18:13 2005 New Revision: 15549 Modified: pypy/dist/LICENSE Log: Fix Guido's name. Dutch rules for spelling say not to capitalise the v in van when the name is spelled in full. Modified: pypy/dist/LICENSE ============================================================================== --- pypy/dist/LICENSE (original) +++ pypy/dist/LICENSE Wed Aug 3 13:18:13 2005 @@ -49,7 +49,7 @@ Jacob Hallen Marius Gedminas Laura Creighton - Guido Van Rossum + Guido van Rossum Richard Emslie Ludovic Aubry Adrien Di Mascio From rxe at codespeak.net Wed Aug 3 14:09:29 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 14:09:29 +0200 (CEST) Subject: [pypy-svn] r15551 - pypy/dist/pypy/translator/llvm2/demo Message-ID: <20050803120929.7403927B54@code1.codespeak.net> Author: rxe Date: Wed Aug 3 14:09:25 2005 New Revision: 15551 Added: pypy/dist/pypy/translator/llvm2/demo/__init__.py pypy/dist/pypy/translator/llvm2/demo/run.py Modified: pypy/dist/pypy/translator/llvm2/demo/ (props changed) pypy/dist/pypy/translator/llvm2/demo/bpnn.py (contents, props changed) pypy/dist/pypy/translator/llvm2/demo/richards.py (contents, props changed) Log: Refactor interface. Added: pypy/dist/pypy/translator/llvm2/demo/__init__.py ============================================================================== Modified: pypy/dist/pypy/translator/llvm2/demo/bpnn.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/bpnn.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/bpnn.py Wed Aug 3 14:09:25 2005 @@ -245,40 +245,5 @@ return 0 if __name__ == "__main__": - from pypy.translator.llvm2.genllvm import compile_function - import py - - import sys - compile_llvm = True - if len(sys.argv) > 1: - if sys.argv[1] == "p": - main() - compile_llvm = False - elif sys.argv[1] == "c": - - from pypy.translator.translator import Translator - t = Translator(main) - a = t.annotate([]) - t.specialize() - f = t.ccompile() - f() - - compile_llvm = False - - if compile_llvm: - compile_function(main, []) - - # generate runnable bytecode with the following command - os.write(1, 'Generating standalone LLVM bytecode:\n') - cmd = "llvmc -O5 -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc /tmp/usession-current/main_optimized.bc -o bpnn" - os.write(1, cmd + '\n') - os.system(cmd) - - # run with the following command - os.write(1, 'Running standalone LLVM bytecode:\n') - cmd = "./bpnn" - os.write(1, cmd + '\n') - os.system(cmd) - - os.write(1, 'Running on top of CPython:\n') - main() + from pypy.translator.llvm2.demo.run import run + run(main, "bpnn") Modified: pypy/dist/pypy/translator/llvm2/demo/richards.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/richards.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/richards.py Wed Aug 3 14:09:25 2005 @@ -1,3 +1,5 @@ +import os + # based on a Java version: # Based on original version written in BCPL by Dr Martin Richards @@ -127,8 +129,6 @@ - - tracing = False layout = 0 @@ -344,8 +344,6 @@ import time - - def schedule(): t = taskWorkArea.taskList while t is not None: @@ -392,21 +390,25 @@ schedule() if taskWorkArea.holdCount == 9297 and taskWorkArea.qpktCount == 23246: - pass + os.write(1, "iteration %d\n" % i) else: return False return True +class FailedRun(Exception): + pass + def entry_point(): r = Richards() + if not r: + raise FailedRun startTime = time.time() result = r.run() endTime = time.time() return result, startTime, endTime def main(): - import os os.write(1, "Richards benchmark (Python) starting... \n") result, startTime, endTime = entry_point() if not result: @@ -419,28 +421,5 @@ return 0 if __name__ == "__main__": - from pypy.translator.llvm2.genllvm import compile_function - import py - - import sys - compile_llvm = True - if len(sys.argv) > 1: - if sys.argv[1] == "p": - main() - compile_llvm = False - elif sys.argv[1] == "c": - - from pypy.translator.translator import Translator - t = Translator(main) - a = t.annotate([]) - t.specialize() - f = t.ccompile() - f() - - compile_llvm = False - - if compile_llvm: - compile_function(main, []) - - # run with the following command - "llvmc -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc main_optimized.bc -o go" + from pypy.translator.llvm2.demo.run import run + run(main, "richards") Added: pypy/dist/pypy/translator/llvm2/demo/run.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm2/demo/run.py Wed Aug 3 14:09:25 2005 @@ -0,0 +1,54 @@ +import py +import os +import sys + +from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.translator import Translator + +def p(): + print 'Running on top of CPython:' + entry_point() + +def c(): + print "Running genc'd version on top of CPython:" + t = Translator(entry_point) + a = t.annotate([]) + t.specialize() + f = t.ccompile() + f() + +def l(name): + compile_function(entry_point, []) + + # generate runnable bytecode with the following command + print 'Generating standalone LLVM bytecode:' + cmd = "llvmc -O5 -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc /tmp/usession-current/main_optimized.bc -o %s" % name + print cmd + os.system(cmd) + + # run with the following command + print 'Running standalone LLVM bytecode:' + cmd = "./%s" % name + print cmd + os.system(cmd) + +def run(ep, name="go"): + global entry_point + entry_point = ep + + run_all = True + if len(sys.argv) > 1: + if sys.argv[1] == "p": + c() + run_all = False + elif sys.argv[1] == "c": + c() + run_all = False + elif sys.argv[1] == "l": + l(name) + run_all = False + + if run_all: + l(name) + c() + p() From hpk at codespeak.net Wed Aug 3 14:35:54 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 3 Aug 2005 14:35:54 +0200 (CEST) Subject: [pypy-svn] r15552 - pypy/dist/pypy/translator/goal Message-ID: <20050803123554.6DC9127B54@code1.codespeak.net> Author: hpk Date: Wed Aug 3 14:35:53 2005 New Revision: 15552 Modified: pypy/dist/pypy/translator/goal/runtranslate.sh pypy/dist/pypy/translator/goal/translate_pypy.py Log: preparing batch mode (translate_pypy.py should then not do interactive stuff) Modified: pypy/dist/pypy/translator/goal/runtranslate.sh ============================================================================== --- pypy/dist/pypy/translator/goal/runtranslate.sh (original) +++ pypy/dist/pypy/translator/goal/runtranslate.sh Wed Aug 3 14:35:53 2005 @@ -2,7 +2,7 @@ # stopping on the first error #python translate_pypy.py -no-c -no-o -text -no-snapshot -fork # running it all -python translate_pypy.py -no-o -text -t-insist -no-snapshot +python translate_pypy.py -no-o -text -t-insist -no-snapshot $* # How to work in parallel: Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Wed Aug 3 14:35:53 2005 @@ -290,6 +290,7 @@ '-save': False, '-fork': False, '-llinterpret': False, + '-batch': False, } listen_port = None argiter = iter(sys.argv[1:]) @@ -504,15 +505,21 @@ print func, args = pdb_plus_show.set_trace, () if options['-text']: - func(*args) + if options['-batch']: + print >>sys.stderr, "batch mode, not calling interactive helpers" + else: + func(*args) else: - start, show, stop, cleanup = run_server() - pdb_plus_show.show = show - debugger = run_in_thread(func, args, stop) - debugger.start() - start() - debugger.join() - cleanup() + if options['-batch']: + print >>sys.stderr, "batch mode, not calling interactive helpers" + else: + start, show, stop, cleanup = run_server() + pdb_plus_show.show = show + debugger = run_in_thread(func, args, stop) + debugger.start() + start() + debugger.join() + cleanup() try: err = None @@ -542,7 +549,11 @@ sys.path.insert(0, os.path.dirname(targetspec)) execfile(targetspec+'.py', targetspec_dic) print "Analysing target as defined by %s" % targetspec - print 'options in effect:', options + print 'options in effect:' + optnames = options.keys() + optnames.sort() + for name in optnames: + print ' %25s: %s' %(name, options[name]) try: analyse(targetspec_dic['target']) except TyperError: @@ -588,6 +599,6 @@ raise except: debug(True) + raise SystemExit(1) else: debug(False) - From ericvrp at codespeak.net Wed Aug 3 15:23:37 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 15:23:37 +0200 (CEST) Subject: [pypy-svn] r15553 - in pypy/dist/pypy/translator/llvm2: . demo Message-ID: <20050803132337.C4A6227B59@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 15:23:36 2005 New Revision: 15553 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/demo/richards.py pypy/dist/pypy/translator/llvm2/demo/run.py pypy/dist/pypy/translator/llvm2/genllvm.py Log: create staticly linked executable in /tmp/usession-current/ (for richards and bpnn benchmarks) Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Wed Aug 3 15:23:36 2005 @@ -18,7 +18,7 @@ SOURCES = "time.ii ".split() -EXCEPTIONS_SWITCHES = "-enable-correct-eh-support" +EXCEPTIONS_SWITCHES = "-enable-correct-eh-support --regalloc iterativescan" OPTIMIZATION_SWITCHES = (" ".join([ @@ -155,7 +155,7 @@ log.build(cmd) cmdexec(cmd) -def make_module_from_llvm(llvmfile, pyxfile, optimize=True): +def make_module_from_llvm(llvmfile, pyxfile, optimize=True, exe_name=None): include_dir = py.magic.autopath().dirpath() dirpath = llvmfile.dirpath() lastdir = path.local() @@ -166,17 +166,22 @@ object_files = [] library_files = [] if use_boehm_gc: + gc_libs = '-lgc -lpthread' library_files.append('gc') + else: + gc_libs = '' if sys.maxint == 2147483647: #32 bit platform if optimize: cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), "opt %s -f %s.bc -o %s_optimized.bc" % (OPTIMIZATION_SWITCHES, b, b), - "llc --regalloc iterativescan %s %s_optimized.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] + "llc %s %s_optimized.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] else: cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), "llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] cmds.append("as %s.s -o %s.o" % (b, b)) + if exe_name: + cmds.append("gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) object_files.append("%s.o" % b) else: #assume 64 bit platform (x86-64?) #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! Modified: pypy/dist/pypy/translator/llvm2/demo/richards.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/richards.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/richards.py Wed Aug 3 15:23:36 2005 @@ -409,7 +409,7 @@ return result, startTime, endTime def main(): - os.write(1, "Richards benchmark (Python) starting... \n") + os.write(1, "Richards benchmark starting... \n") result, startTime, endTime = entry_point() if not result: os.write(1, "Incorrect results!\n") @@ -421,5 +421,6 @@ return 0 if __name__ == "__main__": + import autopath from pypy.translator.llvm2.demo.run import run run(main, "richards") Modified: pypy/dist/pypy/translator/llvm2/demo/run.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/run.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/run.py Wed Aug 3 15:23:36 2005 @@ -18,17 +18,9 @@ f() def l(name): - compile_function(entry_point, []) - - # generate runnable bytecode with the following command - print 'Generating standalone LLVM bytecode:' - cmd = "llvmc -O5 -Tasm=-enable-correct-eh-support -v -L /usr/lib/ -lm -lgc /tmp/usession-current/main_optimized.bc -o %s" % name - print cmd - os.system(cmd) - - # run with the following command - print 'Running standalone LLVM bytecode:' - cmd = "./%s" % name + compile_function(entry_point, [], exe_name=name) + print 'Running standalone (llvm-based) executable:' + cmd = "/tmp/usession-current/%s" % name print cmd os.system(cmd) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Wed Aug 3 15:23:36 2005 @@ -160,7 +160,7 @@ self.content = str(codewriter) return self.content - def create_module(self): + def create_module(self, exe_name=None): # hack to prevent running the same function twice in a test func = self.entrypoint if func.func_name in function_count: @@ -181,16 +181,15 @@ pyxsource = llvmsource.new(basename=llvmsource.purebasename+'_wrapper'+postfix+'.pyx') write_pyx_wrapper(self.entrynode, pyxsource) - return build_llvm_module.make_module_from_llvm(llvmsource, pyxsource) + return build_llvm_module.make_module_from_llvm(llvmsource, pyxsource, exe_name=exe_name) def _debug_prototype(self, codewriter): codewriter.append("declare int %printf(sbyte*, ...)") - -def genllvm(translator, embedexterns=True): +def genllvm(translator, embedexterns=True, exe_name=None): gen = GenLLVM(translator, embedexterns=embedexterns) log.genllvm(gen.compile()) - return gen.create_module() + return gen.create_module(exe_name) def llvm_is_on_path(): try: @@ -199,19 +198,19 @@ return False return True -def compile_module(function, annotate, view=False, embedexterns=True): +def compile_module(function, annotate, view=False, embedexterns=True, exe_name=None): t = Translator(function) a = t.annotate(annotate) t.specialize() if view: t.view() - return genllvm(t, embedexterns=embedexterns) + return genllvm(t, embedexterns=embedexterns, exe_name=exe_name) -def compile_function(function, annotate, view=False, embedexterns=True): - mod = compile_module(function, annotate, view, embedexterns=embedexterns) +def compile_function(function, annotate, view=False, embedexterns=True, exe_name=None): + mod = compile_module(function, annotate, view, embedexterns=embedexterns, exe_name=exe_name) return getattr(mod, function.func_name + "_wrapper") -def compile_module_function(function, annotate, view=False, embedexterns=True): - mod = compile_module(function, annotate, view, embedexterns=embedexterns) +def compile_module_function(function, annotate, view=False, embedexterns=True, exe_name=None): + mod = compile_module(function, annotate, view, embedexterns=embedexterns, exe_name=exe_name) f = getattr(mod, function.func_name + "_wrapper") return mod, f From ericvrp at codespeak.net Wed Aug 3 15:28:12 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 15:28:12 +0200 (CEST) Subject: [pypy-svn] r15554 - pypy/dist/pypy/translator/llvm2/demo Message-ID: <20050803132812.4930127B59@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 15:28:11 2005 New Revision: 15554 Modified: pypy/dist/pypy/translator/llvm2/demo/run.py Log: fixed typo Modified: pypy/dist/pypy/translator/llvm2/demo/run.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/run.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/run.py Wed Aug 3 15:28:11 2005 @@ -31,7 +31,7 @@ run_all = True if len(sys.argv) > 1: if sys.argv[1] == "p": - c() + p() run_all = False elif sys.argv[1] == "c": c() From nik at codespeak.net Wed Aug 3 15:50:14 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 3 Aug 2005 15:50:14 +0200 (CEST) Subject: [pypy-svn] r15555 - in pypy/dist: lib-python pypy Message-ID: <20050803135014.3A05C27B4D@code1.codespeak.net> Author: nik Date: Wed Aug 3 15:50:12 2005 New Revision: 15555 Modified: pypy/dist/lib-python/conftest.py pypy/dist/pypy/conftest.py Log: added --usemodules option to py.test Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 3 15:50:12 2005 @@ -355,10 +355,7 @@ RegrTest('test_al.py', enabled=False, dumbtest=1), RegrTest('test_anydbm.py', enabled=True, core=True), RegrTest('test_applesingle.py', enabled=False), - RegrTest('test_array.py', enabled=False), - # c-extension - #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser - + RegrTest('test_array.py', enabled=True), RegrTest('test_asynchat.py', enabled=False), RegrTest('test_atexit.py', enabled=False, dumbtest=1, core=True), RegrTest('test_audioop.py', enabled=False, dumbtest=1), @@ -850,7 +847,9 @@ if regrtest.oldstyle: pypy_options.append('--oldstyle') if regrtest.uselibfile: - pypy_options.append('--file') + pypy_options.append('--file') + pypy.options.extend( + ['--usemodules=%s' % mod for mod in pypy_option.usemodules]) sopt = " ".join(pypy_options) if regrtest.getoutputpath(): Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Wed Aug 3 15:50:12 2005 @@ -16,6 +16,9 @@ # group = "pypy options" # optionlist = +def usemodules_callback(option, opt, value, parser): + parser.values.usemodules.append(value) + option = py.test.Config.addoptions("pypy options", Option('-O', '--objspace', action="store", default=None, type="string", dest="objspace", @@ -30,6 +33,9 @@ help="avoid faking of modules and objects completely."), Option('--allpypy', action="store_true",dest="allpypy", default=False, help="run everything possible on top of PyPy."), + Option('--usemodules', action="callback", type="string", metavar="NAME", + callback=usemodules_callback, default=[], + help="(mixed) modules to use."), ) def getobjspace(name=None, _spacecache={}): @@ -45,6 +51,7 @@ space = Space(uselibfile=option.uselibfile, nofaking=option.nofaking, oldstyle=option.oldstyle, + usemodules=option.usemodules ) except KeyboardInterrupt: raise From nik at codespeak.net Wed Aug 3 15:52:43 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 3 Aug 2005 15:52:43 +0200 (CEST) Subject: [pypy-svn] r15557 - pypy/dist/lib-python Message-ID: <20050803135243.0106A27B4D@code1.codespeak.net> Author: nik Date: Wed Aug 3 15:52:43 2005 New Revision: 15557 Modified: pypy/dist/lib-python/conftest.py Log: oops, accidentally enabled test_array in the previous commit Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 3 15:52:43 2005 @@ -355,7 +355,7 @@ RegrTest('test_al.py', enabled=False, dumbtest=1), RegrTest('test_anydbm.py', enabled=True, core=True), RegrTest('test_applesingle.py', enabled=False), - RegrTest('test_array.py', enabled=True), + RegrTest('test_array.py', enabled=False), RegrTest('test_asynchat.py', enabled=False), RegrTest('test_atexit.py', enabled=False, dumbtest=1, core=True), RegrTest('test_audioop.py', enabled=False, dumbtest=1), From rxe at codespeak.net Wed Aug 3 16:52:01 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 16:52:01 +0200 (CEST) Subject: [pypy-svn] r15562 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050803145201.43C7B27B4D@code1.codespeak.net> Author: rxe Date: Wed Aug 3 16:52:00 2005 New Revision: 15562 Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: Raising an exception in outside function and then caught by Exception. Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Wed Aug 3 16:52:00 2005 @@ -198,7 +198,26 @@ assert f(6) == fn(6) assert f(13) == fn(13) -def test_try_raise_choose(): - f = compile_function(try_raise_choose, [int]) - for i in [-1, 0, 1, 2]: - assert f(i) == i +def test_raise_outside_testfn(): + def raiser(n): + if n < 0: + raise ValueError("hello") + else: + raise MyException("world") + + def intermediate(n): + raiser(n) + + def testfn(n): + try: + intermediate(n) + except ValueError: + return 1 + except Exception: + return 2 + return 0 + + f = compile_function(testfn, [int], view=True) + assert f(1) == testfn(1) + assert f(-1) == testfn(-1) + From rxe at codespeak.net Wed Aug 3 16:54:29 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 16:54:29 +0200 (CEST) Subject: [pypy-svn] r15563 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050803145429.DD7CD27B4D@code1.codespeak.net> Author: rxe Date: Wed Aug 3 16:54:28 2005 New Revision: 15563 Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: Oops - commented out test accidentally and forget skip line. Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Wed Aug 3 16:54:28 2005 @@ -198,7 +198,13 @@ assert f(6) == fn(6) assert f(13) == fn(13) +def test_try_raise_choose(): + f = compile_function(try_raise_choose, [int]) + for i in [-1, 0, 1, 2]: + assert f(i) == i + def test_raise_outside_testfn(): + py.test.skip("dont know if this is valid or not") def raiser(n): if n < 0: raise ValueError("hello") From pedronis at codespeak.net Wed Aug 3 16:58:57 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 3 Aug 2005 16:58:57 +0200 (CEST) Subject: [pypy-svn] r15564 - pypy/dist/pypy/translator/goal Message-ID: <20050803145857.3226927B4D@code1.codespeak.net> Author: pedronis Date: Wed Aug 3 16:58:56 2005 New Revision: 15564 Modified: pypy/dist/pypy/translator/goal/query.py Log: sanity check query about methods, at least once it releaved problems with three method impls not appearing in the s_value of the corresponding attribute on W_Root Modified: pypy/dist/pypy/translator/goal/query.py ============================================================================== --- pypy/dist/pypy/translator/goal/query.py (original) +++ pypy/dist/pypy/translator/goal/query.py Wed Aug 3 16:58:56 2005 @@ -441,3 +441,40 @@ except: import traceback traceback.print_exc() + +def sanity_check_methods(translator): + from pypy.annotation.classdef import ClassDef + def ismeth(s_val): + if not isinstance(s_val, annmodel.SomePBC): + return False + s_pbc = s_val + c = 0 + for f, clsdef in s_pbc.prebuiltinstances.iteritems(): + if callable(f) and isinstance(clsdef, ClassDef): + c += 1 + return c == len(s_pbc.prebuiltinstances) + usercls = translator.annotator.getuserclasses() + withmeths = [] + for clsdef in usercls.itervalues(): + meths = [] + for attr in clsdef.attrs.values(): + if ismeth(attr.s_value): + meths.append(attr) + if meths: + withmeths.append((clsdef, meths)) + for clsdef, meths in withmeths: + cls = clsdef.cls + n = 0 + subclasses = [] + for clsdef1 in usercls.itervalues(): + if issubclass(clsdef1.cls, cls): + subclasses.append(clsdef1) + for meth in meths: + name = meth.name + funcs = dict.fromkeys(meth.s_value.prebuiltinstances.iterkeys()) + for subcls in subclasses: + f = subcls.cls.__dict__.get(name) + if f: + if f not in funcs: + print name, subcls.cls, cls, subcls.attrs.keys() + From rxe at codespeak.net Wed Aug 3 17:47:11 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 17:47:11 +0200 (CEST) Subject: [pypy-svn] r15567 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050803154711.2BBF427B52@code1.codespeak.net> Author: rxe Date: Wed Aug 3 17:47:09 2005 New Revision: 15567 Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: See the skip line! :-) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Wed Aug 3 17:47:09 2005 @@ -204,7 +204,7 @@ assert f(i) == i def test_raise_outside_testfn(): - py.test.skip("dont know if this is valid or not") + py.test.skip("Test needs --nomagic!") def raiser(n): if n < 0: raise ValueError("hello") @@ -223,7 +223,7 @@ return 2 return 0 - f = compile_function(testfn, [int], view=True) + f = compile_function(testfn, [int]) assert f(1) == testfn(1) assert f(-1) == testfn(-1) From ale at codespeak.net Wed Aug 3 18:03:44 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 3 Aug 2005 18:03:44 +0200 (CEST) Subject: [pypy-svn] r15568 - pypy/dist/pypy/lib Message-ID: <20050803160344.6D22727B49@code1.codespeak.net> Author: ale Date: Wed Aug 3 18:03:43 2005 New Revision: 15568 Modified: pypy/dist/pypy/lib/_exceptions.py Log: Allow less strict checks on arguments to SyntaxError. Fixes some failures like "TypeError: argument 1 must be str, not ...." I have not been able to add this functionality to _enum_exceptions.py Modified: pypy/dist/pypy/lib/_exceptions.py ============================================================================== --- pypy/dist/pypy/lib/_exceptions.py (original) +++ pypy/dist/pypy/lib/_exceptions.py Wed Aug 3 18:03:43 2005 @@ -259,11 +259,11 @@ self.filename = args[1][0] else: raise TypeError('argument 1 must be str, not %s'%type(args[1][0])) - if type(args[1][1]) == int: + if args[1][1] is None or type(args[1][1]) == int: self.lineno = args[1][1] else: raise TypeError('argument 2 must be str, not %s'%type(args[1][1])) - if type(args[1][2]) == int: + if args[1][2] is None or type(args[1][2]) == int: self.offset = args[1][2] else: raise TypeError('argument 3 must be str, not %s'%type(args[1][2])) From cfbolz at codespeak.net Wed Aug 3 18:29:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 3 Aug 2005 18:29:17 +0200 (CEST) Subject: [pypy-svn] r15570 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050803162917.2AAC127B51@code1.codespeak.net> Author: cfbolz Date: Wed Aug 3 18:29:16 2005 New Revision: 15570 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: added all remaining tests from test_lltype (most of them disabled). Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Wed Aug 3 18:29:16 2005 @@ -162,7 +162,7 @@ raise TypeError("%r instance is not an array" % (self._T,)) def __nonzero__(self): - return self._address != lladdres.NULL + return self._address != lladdress.NULL def __eq__(self, other): if not isinstance(other, simulatorptr): @@ -208,3 +208,7 @@ result._zero_initialize(n) result._init_size(n) return result + +def nullptr(T): + return simulatorptr(lltype.Ptr(T), lladdress.NULL) + Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Wed Aug 3 18:29:16 2005 @@ -131,3 +131,184 @@ assert p4 == p1 SUnrelated = lltype.Struct("unrelated") py.test.raises(TypeError, "cast_pointer(lltype.Ptr(SUnrelated), p3)") + +def test_cast_simple_widening2(): + S2 = lltype.GcStruct("s2", ('a', lltype.Signed)) + S1 = lltype.GcStruct("s1", ('sub1', S2)) + p1 = malloc(S1) + p2 = p1.sub1 + assert lltype.typeOf(p2) == lltype.Ptr(S2) + p3 = cast_pointer(lltype.Ptr(S1), p2) + assert p3 == p1 + p2 = malloc(S2) + +def test_cast_pointer(): + S3 = lltype.GcStruct("s3", ('a', lltype.Signed)) + S2 = lltype.GcStruct("s3", ('sub', S3)) + S1 = lltype.GcStruct("s1", ('sub', S2)) + p1 = malloc(S1) + p2 = p1.sub + p3 = p2.sub + p12 = cast_pointer(lltype.Ptr(S1), p2) + assert p12 == p1 + p13 = cast_pointer(lltype.Ptr(S1), p3) + assert p13 == p1 + p21 = cast_pointer(lltype.Ptr(S2), p1) + assert p21 == p2 + p23 = cast_pointer(lltype.Ptr(S2), p3) + assert p23 == p2 + p31 = cast_pointer(lltype.Ptr(S3), p1) + assert p31 == p3 + p32 = cast_pointer(lltype.Ptr(S3), p2) + assert p32 == p3 + p3 = malloc(S3) + p2 = malloc(S2) + S0 = lltype.GcStruct("s0", ('sub', S1)) + p0 = malloc(S0) + assert p0 == cast_pointer(lltype.Ptr(S0), p0) + p3 = cast_pointer(lltype.Ptr(S3), p0) + p03 = cast_pointer(lltype.Ptr(S0), p3) + assert p0 == p03 + S1bis = lltype.GcStruct("s1b", ('sub', S2)) + assert S1bis != S1 + p1b = malloc(S1bis) + p3 = p1b.sub.sub + assert p1b == cast_pointer(lltype.Ptr(S1bis), p3) + +def DONOTtest_best_effort_gced_parent_detection(): + S2 = lltype.Struct("s2", ('a', lltype.Signed)) + S1 = lltype.GcStruct("s1", ('sub1', S2), ('sub2', S2), + ('tail', lltype.Array(('e', lltype.Signed)))) + p1 = malloc(S1, 1) + p2 = p1.sub2 + assert p2.a == 0 + p3 = p1.tail + p3[0].e = 1 + assert p3[0].e == 1 + del p1 + import gc + gc.collect() + py.test.raises(RuntimeError, "p2.a") + py.test.raises(RuntimeError, "p3[0]") + +def DONOTtest_best_effort_gced_parent_for_arrays(): + A1 = lltype.GcArray(('v', lltype.Signed)) + p1 = malloc(A1, 10) + p1[5].v=3 + assert p1[0].v == 0 + assert p1[9].v == 0 + assert p1[5].v == 3 + p1_5 = p1[5] + del p1 + import gc + gc.collect() + py.test.raises(RuntimeError, "p1_5.v") + + +def DONOTtest_functions(): + F = lltype.FuncType((Signed,), Signed) + py.test.raises(TypeError, "lltype.Struct('x', ('x', F))") + PF = Ptr(F) + pf = PF._example() + assert pf(0) == 0 + py.test.raises(TypeError, pf, 0, 0) + py.test.raises(TypeError, pf, 'a') + + +def test_forward_reference(): + F = lltype.GcForwardReference() + S = lltype.GcStruct('abc', ('x', lltype.Ptr(F))) + F.become(S) + s = malloc(S) + s.x = s + assert s.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x == s + +def test_nullptr(): + S = lltype.Struct('s') + p0 = nullptr(S) + assert not p0 + assert lltype.typeOf(p0) == lltype.Ptr(S) + +def test_nullptr_cast(): + S = lltype.Struct('s') + p0 = nullptr(S) + assert not p0 + S1 = lltype.Struct("s1", ('s', S)) + p10 = cast_pointer(lltype.Ptr(S1), p0) + assert lltype.typeOf(p10) == lltype.Ptr(S1) + assert not p10 + + +def DONOTtest_array_with_non_container_elements(): + As = lltype.GcArray(lltype.Signed) + a = malloc(As, 3) + assert a[0] == 0 + assert a[1] == 0 + assert a[2] == 0 + a[1] = 3 + assert a[1] == 3 + S = lltype.GcStruct('s', ('x', lltype.Signed)) + s = malloc(S) + py.test.raises(TypeError, "a[1] = s") + S = lltype.GcStruct('s', ('x', lltype.Signed)) + S = lltype.Struct('s', ('x', lltype.Signed)) + A = lltype.GcArray(S) + a = malloc(A, 2) + a[0] = malloc(S) + +def DONOTtest_immortal_parent(): + S1 = GcStruct('substruct', ('x', Signed)) + S = GcStruct('parentstruct', ('s1', S1)) + p = malloc(S, immortal=True) + p1 = p.s1 + p1.x = 5 + del p + p = cast_pointer(Ptr(S), p1) + assert p.s1.x == 5 + +def DONOTtest_getRuntimeTypeInfo(): + S = GcStruct('s', ('x', Signed)) + py.test.raises(ValueError, "getRuntimeTypeInfo(S)") + pinf0 = attachRuntimeTypeInfo(S) + assert pinf0._obj.about == S + pinf = getRuntimeTypeInfo(S) + assert pinf == pinf0 + pinf1 = getRuntimeTypeInfo(S) + assert pinf == pinf1 + Z = GcStruct('z', ('x', Unsigned)) + attachRuntimeTypeInfo(Z) + assert getRuntimeTypeInfo(Z) != pinf0 + Sbis = GcStruct('s', ('x', Signed)) + attachRuntimeTypeInfo(Sbis) + assert getRuntimeTypeInfo(Sbis) != pinf0 + assert Sbis != S # the attached runtime type info distinguishes them + +def DONOTtest_runtime_type_info(): + S = GcStruct('s', ('x', Signed)) + attachRuntimeTypeInfo(S) + s = malloc(S) + assert runtime_type_info(s) == getRuntimeTypeInfo(S) + S1 = GcStruct('s1', ('sub', S), ('x', Signed)) + attachRuntimeTypeInfo(S1) + s1 = malloc(S1) + assert runtime_type_info(s1) == getRuntimeTypeInfo(S1) + assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1) + assert runtime_type_info(cast_pointer(Ptr(S), s1)) == getRuntimeTypeInfo(S1) + def dynamic_type_info_S(p): + if p.x == 0: + return getRuntimeTypeInfo(S) + else: + return getRuntimeTypeInfo(S1) + fp = functionptr(FuncType([Ptr(S)], Ptr(RuntimeTypeInfo)), + "dynamic_type_info_S", + _callable=dynamic_type_info_S) + attachRuntimeTypeInfo(S, fp) + assert s.x == 0 + assert runtime_type_info(s) == getRuntimeTypeInfo(S) + s.x = 1 + py.test.raises(RuntimeError, "runtime_type_info(s)") + assert s1.sub.x == 0 + py.test.raises(RuntimeError, "runtime_type_info(s1.sub)") + s1.sub.x = 1 + assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1) + From ale at codespeak.net Wed Aug 3 18:35:29 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 3 Aug 2005 18:35:29 +0200 (CEST) Subject: [pypy-svn] r15571 - pypy/dist/lib-python Message-ID: <20050803163529.9744027B49@code1.codespeak.net> Author: ale Date: Wed Aug 3 18:35:28 2005 New Revision: 15571 Modified: pypy/dist/lib-python/conftest.py Log: typo Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 3 18:35:28 2005 @@ -848,7 +848,7 @@ pypy_options.append('--oldstyle') if regrtest.uselibfile: pypy_options.append('--file') - pypy.options.extend( + pypy_options.extend( ['--usemodules=%s' % mod for mod in pypy_option.usemodules]) sopt = " ".join(pypy_options) From pedronis at codespeak.net Wed Aug 3 19:10:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 3 Aug 2005 19:10:13 +0200 (CEST) Subject: [pypy-svn] r15572 - pypy/dist/pypy/tool Message-ID: <20050803171013.6499227B4D@code1.codespeak.net> Author: pedronis Date: Wed Aug 3 19:10:12 2005 New Revision: 15572 Added: pypy/dist/pypy/tool/_enum_exceptions_broken.py - copied unchanged from r15559, pypy/dist/pypy/tool/_enum_exceptions.py Removed: pypy/dist/pypy/tool/_enum_exceptions.py Log: renamed _enum_exceptions to mark that is not usable anymore. it would need an extensive rewrite at this point. Deleted: /pypy/dist/pypy/tool/_enum_exceptions.py ============================================================================== --- /pypy/dist/pypy/tool/_enum_exceptions.py Wed Aug 3 19:10:12 2005 +++ (empty file) @@ -1,402 +0,0 @@ -# XXX this does not produce a correct _exceptions anymore because the logic to reconstruct -# type checks is broken - -# this script is used for extracting -# the information available for exceptions -# via introspection. -# The idea is to use it once to create -# a template for a re-birth of exceptions.py - -import autopath -import types -from pypy.tool.sourcetools import render_docstr - -def classOfAttribute(klass, attname): - if attname in klass.__dict__: - return klass - for base in klass.__bases__: - ret = classOfAttribute(base, attname) - if ret: - return ret - -def getAttributes(klass, ignorelist = []): - return [name for name in dir(klass) if name not in ignorelist] - -def makeExceptionsTemplate(f=None): - - def enumClassesInOrder(module): - seen = {} - ordered = [] - - def enumerateOne(exc): - seen[exc] = 1 - for each in exc.__bases__: - if each not in seen: - enumerateOne(each) - ordered.append(exc) - - for each in module.__dict__.values(): - if isinstance(each, (types.ClassType, type)) and \ - each not in seen: - enumerateOne(each) - - return ordered - - if not f: - f = sys.stdout - - import exceptions - print >> f, render_docstr(exceptions, "") - - for exc in enumClassesInOrder(exceptions): - name = exc.__name__ - bases = exc.__bases__ - doc = exc.__doc__ - bases = [this.__name__ for this in bases] - bases = ", ".join(bases) - if bases: bases = "(%s)" % bases - - ignorelist = "__doc__ __module__".split() - # find out class variables and methods - simple = [] - difficult = [] - for attname in getAttributes(exc, ignorelist): - if classOfAttribute(exc, attname) is exc: - obj = getattr(exc, attname) - (simple, difficult)[callable(obj)].append( (attname, obj) ) - print >> f - print >> f, "class %s%s:" % (name, bases) - if doc: - print >> f, ' """%s"""' % doc - if not (simple or difficult or doc): - print >> f, " pass" - for tup in simple: - print >> f, " %s = %r" % tup - - for attname, meth in difficult: - print >> f - func = globals().get("tryGenerate" + attname, None) - if not func: - print >> f, " # please implement %s.%s (%r)" % (name, attname, meth) - else: - try: - for line in func(exc): - print >> f, " " + line - except ValueError, e: - print >> f, " # %s" % e - print >> f, " # please implement %s.%s (%r)" % (name, attname, meth) - -def tryGenerate__getitem__(exc): - for args in (), (1, 2, 3): - try: - sample = exc(*args) - except: - raise ValueError, "cannot create instance" - if "args" not in sample.__dict__: - raise ValueError, "args attribute not found in __dict__" - if args != sample.args: - raise ValueError, "instance has modified args" - for i in range(5): - try: x = sample[i] - except IndexError: x = 42 - try: y = args[i] - except IndexError: y = 42 - if x != y: - raise ValueError, "args does not behave like a sequence" - del sample.args - try: x = sample[0] - except: x = 42 - use_default = x is None - # looks fine so far. - yield "# auto-generated code, please check carefully!" - yield "def __getitem__(self, idx):" - if use_default: - yield " if not hasattr(self, 'args'):" - yield " return None" - yield " return self.args[idx]" - - -class ProbeObject(object): - """ this class creates general "any" objects, and - for the special case of SyntaxError, it can behave - like a subscriptable object - """ - def __init__(self, argpos, maxprobe=None): - self.argpos = argpos - self.maxprobe = maxprobe - self.probed = [] - def __getitem__(self, idx): - if idx not in self.probed: - self.probed.append(idx) - if self.maxprobe is not None and idx > self.maxprobe: - raise IndexError, "cheat cheat %d" % idx - return "arg%d_%s" % (self.argpos, idx) - def __repr__(self): - if self.probed: - return "" % (self.argpos, self.probed) - else: - return "" % self.argpos - def __str__(self): - # make this different from repr! - return repr(self)[1:-1] - def __cmp__(self, other): - return cmp( (self.argpos, self.probed), other) - -def genArgsToTry(argpos): - args = [ProbeObject(argpos), - "arg%d" % argpos, u"arg%d" %argpos, 1000+argpos*10] - return args - -def cartesian(*args): - if len(args)== 0: - yield args - elif len(args) == 1: - for item in args[0]: - yield (item,) - else: - for item in args[0]: - for other in cartesian(*args[1:]): - yield (item,) + other - -def probeArgCount(exc, maxprobe=20): - worksmaybe = [] - for i in range(maxprobe): - try: - probe = exc(*(i,)*i) # test i-tuple - worksmaybe.append(i) - except TypeError, e: - if not str(e).startswith("function takes "): - worksmaybe.append(i) - except: - pass - return min(worksmaybe), max(worksmaybe) - -def refreshArgs(tup): - res = [] - for arg in tup: - if type(arg) is ProbeObject: - arg = ProbeObject(arg.argpos) # cleanup probing - res.append(arg) - return tuple(res) - -def findAllArgs(exc, maxprobe): - minargs, maxargs = probeArgCount(exc, maxprobe) - res = [] - # for minargs args, we need to try combinations - arglist = tuple([genArgsToTry(i) for i in range(minargs)]) - for args in cartesian(*arglist): - try: - probe = exc(*args) - res.append(args) - works = refreshArgs(args) - break - except Exception, e: - continue - else: - raise TypeError, "cannot analyse arguments of %s" % exc.__name__ - # for the variable part, don't try combinations - for i in range(minargs, maxargs): - for arg in genArgsToTry(i): - args = works + (arg,) - try: - probe = exc(*args) - res.append(args) - works = refreshArgs(args) - break - except: - continue - else: - raise TypeError, "cannot analyse arguments of %s" % exc.__name__ - return minargs, maxargs, res - -def captureAssignments(exc, args): - """ we wrap a class around the exc class and record attribute access """ - assigned = [] - class WrapExc(exc): - def __setattr__(self, name, obj): - assigned.append( (name, obj) ) - self.__dict__[name] = obj - probe = WrapExc(*args) - names = {} - names[args] = "args" - for i, arg in enumerate(args): - names[arg] = "args[%d]" % i - if not isinstance(arg, ProbeObject): - continue - for subidx in arg.probed: - names[arg[subidx]] = "args[%d][%d]" % (i, subidx) - def nameof(obj): - if obj in names: - return names[obj] - elif isinstance(obj, (tuple, list)): - stuff = [nameof(x) for x in obj] - br = str(type(obj)()) - txt = br[0] + ", ".join(stuff) + br[-1] - names[obj] = txt - else: - names[obj] = "%r" % obj - return names[obj] - res = [] - for i,(name, obj) in enumerate(assigned): - if isinstance(obj,ProbeObject) or name == 'args' or obj==None: - res.append("self.%s = %s" % (name, nameof(obj))) - else: - res.append("if type(%s) == %s:"%(nameof(obj),repr(type(obj))[7:-2])) - res.append(" self.%s = %s" % (name, nameof(obj))) - res.append("else:") - reason ="argument %i must be %s, not %s"%(i-1,repr(type(obj))[7:-2],'%s') - reason2=''.join(["%type(","%s"%nameof(obj),")"]) - reason = "'"+ reason+"'" +reason2 - res.append(" raise TypeError(%s)"%(reason)) - return tuple(res) - -def tryGenerate__init__(exc, maxprobe=20): - minargs, maxargs, working = findAllArgs(exc, maxprobe) - # merge assignments in order, record set of arg counts - foldcases = {} - for args in working: - singleprog = captureAssignments(exc, args) - for tup in enumerate(singleprog): - foldcases.setdefault(tup, []) - foldcases[tup].append(len(args)) - # group assignments by set of arg counts and order - groupassign = {} - for (order, assignment), argcounts in foldcases.items(): - key = tuple(argcounts) - # special case: we don't raise errors - # and always assign to self.args - if assignment == "self.args = args" and len(key) != maxprobe: - assignment += " # modified: always assign args, no error check" - key = tuple(range(maxprobe)) - groupassign.setdefault(key, []) - groupassign[key].append( (order, assignment) ) - cases = groupassign.items() - cases.sort() - yield "# auto-generated code, please check carefully!" - yield "def __init__(self, *args):" - if len(cases) > 1 or len(cases[0][0]) != maxprobe: - yield " argc = len(args)" - for argcounts, ordered_statements in cases: - ordered_statements.sort() - trailer = None - if len(argcounts) == maxprobe: - # all counts, no condition - indent = 1 - else: - indent = 2 - dense = tuple(range(argcounts[0], argcounts[-1]+1)) == argcounts - if len(argcounts) == 1: - yield " if argc == %d:" % argcounts - if maxargs == minargs: - trailer = [" else:"] - err_msg = "" - trailer += [" raise TypeError('function takes exactly "+str(argcounts[0])+" arguments (%d given)'%argc)"] - elif dense and argcounts[0] == 0: - yield " if argc <= %d:" % argcounts[-1] - elif dense and argcounts[-1] == maxprobe-1: - yield " if argc >= %d:" % argcounts[0] - elif dense: - yield " if %d <= argc <= %d:" % (argcounts[0], argcounts[-1]) - else: - yield " if argc in %r:" % (argcounts, ) - if len(ordered_statements)>0: - for order, line in ordered_statements: - yield indent * " " + line - else: - yield indent * " " + "pass" - if trailer: - for line in trailer : yield line - -def tryGenerate__str__(exc, maxprobe=20): - if exc in known__str__: - import inspect - src = inspect.getsource(known__str__[exc]) - for line in src.split("\n"): - yield line - return - - minargs, maxargs, working = findAllArgs(exc, maxprobe) - # checking the default case (well, there are two) - simple = False - arg1_methods = [] - for args in working: - test = str(exc(*args)) - if len(args) == 0 and test != "": - break - if len(args) == 1: - if test == repr(args[0]): - arg1_methods.append("repr") - elif test == str(args[0]): - arg1_methods.append("str") - else: - break - if len(args) >= 2 and test != repr(args): - break - else: - simple = arg1_methods and min(arg1_methods) == max(arg1_methods) - yield "# auto-generated code, please check carefully!" - if simple: - yield "def __str__(self):" - yield " args = self.args" - yield " argc = len(args)" - yield " if argc == 0:" - yield " return ''" - yield " elif argc == 1:" - yield " return %s(args[0])" % arg1_methods.pop() - yield " else:" - yield " return str(args)" - return - # no idea how I should do this - probe = exc(*working[0]) - dic = probe.__dict__ - for key in dic.keys(): - if key.startswith("__") and key.endswith("__"): - del dic[key] - yield "def __str__(self):" - yield " # this is a bad hack, please supply an implementation" - yield " res = ' '.join([" - for key in dic.keys(): - yield " '%s=' + str(getattr(self, '%s', None))," % (key, key) - yield " ])" - yield " return res" - -known__str__ = {} - -# SyntaxError -def __str__(self): - if type(self.msg) is not str: - return self.msg - - buffer = self.msg - have_filename = type(self.filename) is str - have_lineno = type(self.lineno) is int - if have_filename or have_lineno: - import os - fname = os.path.basename(self.filename or "???") - if have_filename and have_lineno: - buffer = "%s (%s, line %ld)" % (self.msg, fname, self.lineno) - elif have_filename: - buffer ="%s (%s)" % (self.msg, fname) - elif have_lineno: - buffer = "%s (line %ld)" % (self.msg, self.lineno) - return buffer -known__str__[SyntaxError] = __str__ - -# EnvironmentError -def __str__(self): - if self.filename is not None: - return "[Errno %s] %s: %s" % (self.errno, - self.strerror, - self.filename) - if self.errno and self.strerror: - return "[Errno %s] %s" % (self.errno, self.strerror) - return StandardError.__str__(self) -known__str__[EnvironmentError] = __str__ - -if __name__ == "__main__": - import pypy, os - prefix = os.path.dirname(pypy.__file__) - libdir = os.path.join(prefix, "lib") - fname = "_exceptions.pre.py" - fpath = os.path.join(libdir, fname) - makeExceptionsTemplate(file(fpath, "w")) From hpk at codespeak.net Wed Aug 3 19:19:16 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 3 Aug 2005 19:19:16 +0200 (CEST) Subject: [pypy-svn] r15573 - pypy/extradoc/minute Message-ID: <20050803171916.2149627B56@code1.codespeak.net> Author: hpk Date: Wed Aug 3 19:19:14 2005 New Revision: 15573 Added: pypy/extradoc/minute/pypy-sync-07-14-2005.txt - copied unchanged from r14720, pypy/extradoc/minute/pypy-sync-07-14.txt Removed: pypy/extradoc/minute/pypy-sync-07-14.txt Modified: pypy/extradoc/minute/ (props changed) pypy/extradoc/minute/pypy-sync-07-21-2005.txt Log: formatting/renaming Deleted: /pypy/extradoc/minute/pypy-sync-07-14.txt ============================================================================== --- /pypy/extradoc/minute/pypy-sync-07-14.txt Wed Aug 3 19:19:14 2005 +++ (empty file) @@ -1,260 +0,0 @@ -============================================= -pypy-sync developer meeting 14th July 2005 -============================================= - - -Attendees: Samuele, Anders C., Anders L., Adrien Di Mascio, Ludovic Aubry, - Christian Tismer, Carl Friedrich Bolz, Holger Krekel - -Excused with Pre-Info: Armin - - -Regular Topics -==================== - -- roll call. OK. - -- activity reports (3 prepared lines of info). - Everybody submitted activity reports (see `IRC-Log`_ at the end) - -- re-assigning / adjusting planning / resolve conflicts/blockers - - Everybody except Anders Lehmann has plans for next week. - No conflicts. Anders L., Samuele and Holger are to try discuss - tasks for Anders outside of this pypy-sync meeting. Holger - notes that he wants to be signalled before the meeting - if somebody is lacking tasks. - -Topics of the week -=================== - -fixating sprint in Hildesheim (25th-31st July) -------------------------------------------------- - -Armin, Samuele, Christian, Carl (except for one day) and Holger -can make it to the Hildesheim sprint. We decided that it will -take place. - -decide/agree about usage of issue tracker (for 0.6.2/0.7.0) ------------------------------------------------------------ - -everybody agrees and recognizes that we are going to use -the issue tracker for the upcoming releases. So be it. - -list current main areas of work regarding reaching Deliverable D05.2 ----------------------------------------------------------------------- - -Armin: Progressing on translate_pypy.py. There is a temp file -pypy/translator/goal/ISSUES.txt which lists currently open issues. -Samuele adds that he has some worries about memory usage -regarding the rtyping process but nothing concrete yet. -Generally the strategy is to try translate_pypy.py with -a different SEED. Christian will add info to ISSUES.txt -about how to use it. - -Heidelberg sprint planning status, 22nd-29th August ----------------------------------------------------------- - -It is re-confirmed that the sprint should take place -from 22nd-29th in Heidelberg, Germany. Carl Friedrich will fix -the place now and report back. We should discuss/prepare -the sprint-announcement regarding topics etc.pp. at the -next sync-meeting. - -Close ---------- - -Holger closes the meeting in time at 13:30pm. - -.. _`IRC-log`: - -Here is the full IRC log:: - - **** BEGIN LOGGING AT Thu Jul 14 13:01:32 2005 - Jul 14 13:01:32 --> You are now talking on #pypy-sync - Jul 14 13:01:32 --- #pypy-sync :[freenode-info] please register your nickname...don't forget to auto-identify! http://freenode.net/faq.shtml#nicksetup - Jul 14 13:02:30 pedronis: hello? - Jul 14 13:02:34 --> adim (~adim at fny94-6-82-229-225-51.fbx.proxad.net) has joined #pypy-sync - Jul 14 13:02:39 hpk: hi - Jul 14 13:03:02 Hi Holger, Hi Samuele - Jul 14 13:03:06 hi adrien - Jul 14 13:03:07 --> cfbolz (~a at zenon.physi.uni-heidelberg.de) has joined #pypy-sync - Jul 14 13:03:10 --> arre (ac at ratthing-b40b.strakt.com) has joined #pypy-sync - Jul 14 13:03:17 --> aleale (~chatzilla at 83.72.68.168.ip.tele2adsl.dk) has joined #pypy-sync - Jul 14 13:03:38 cfbolz: hi carl - Jul 14 13:03:49 ok, i think we can start the meeting. - Jul 14 13:03:56 armin send me info already he might make it later - Jul 14 13:04:00 --> ludal (~ludal at lab75-1-81-57-254-81.fbx.proxad.net) has joined #pypy-sync - Jul 14 13:04:08 christian didn't say anything, though - Jul 14 13:04:11 anyway. - Jul 14 13:04:24 the idea is to really stick to the 30 minutes, we will end the meeting at 13:30 - Jul 14 13:04:37 so don't walk away to grab a coffee or something :-) - Jul 14 13:04:46 here is the agenda: - Jul 14 13:04:53 - roll call - Jul 14 13:04:53 - activity reports (3 prepared lines of info) - Jul 14 13:04:53 - re-assigning / adjusting planning / resolve conflicts/blockers - Jul 14 13:04:53 - Topics of the week: - Jul 14 13:04:53 - fixating sprint in Hildesheim (25th-31st July) - Jul 14 13:04:53 - decide/agree about usage of issue tracker (for 0.6.2/0.7.0) - Jul 14 13:04:53 - list current main areas of work regarding reaching Deliverable D05.2 - Jul 14 13:04:53 - Heidelberg sprint planning status (now: 15-22th August !!!) - Jul 14 13:05:19 everybody fine with this agenda? - Jul 14 13:05:27 yes - Jul 14 13:05:30 yes - Jul 14 13:05:36 yes - Jul 14 13:05:55 yes - Jul 14 13:05:55 yes - Jul 14 13:05:56 ok, then activity reports: i'll just start off with my and Armin's info: - Jul 14 13:06:03 last week: begin interpreter-docs, fix codespeak/website issues, fix testresults page, some eu/managementissues - Jul 14 13:06:03 next week: finish interpreter docs, write external (oslevel) functions, prepare codespeak-move - Jul 14 13:06:03 blocking: (slightly) terminology cleanup / missing glossary / (maybe llvm-state) - Jul 14 13:06:14 --- You are now known as arigo - Jul 14 13:06:28 last week: rtyper; progress in translate_pypy; polished framework for external func calls. - Jul 14 13:06:28 next week: holidays until wednesday - Jul 14 13:06:28 blockers: None - Jul 14 13:06:35 --- You are now known as hpk - Jul 14 13:06:40 last week: logistics, accomodation for Heidelberg sprint; own stuff - Jul 14 13:06:40 next week: more logistics; garbage collection - Jul 14 13:06:40 blockers: my own stuff takes too much time :-( - Jul 14 13:06:41 pedronis: you continue? - Jul 14 13:06:49 cfbolz: ok - Jul 14 13:06:49 sorry - Jul 14 13:06:52 np - Jul 14 13:07:00 DONE: translate_pypy progress, instatiate of classes with Armin...; solved some attributes that were attached too high the hierarchy, some support for pyobjs ops in the llinterp, and more work with Arre on translate_pypy; refactored rtyper to use argument.py for args parsing and call_args support - Jul 14 13:07:01 NEXT: more translate_pypy work, possibly refactor specialisation to treats override and memos as builtins, refactor gencapi usage to go through external func table - Jul 14 13:07:03 ISSUES: a bit worried about rtyping mem usage but too soon too really tell - Jul 14 13:07:43 adim, ludal, aleale, arre: in this order? - Jul 14 13:07:44 --> stakkars (ihdhcvza at i528C1A57.versanet.de) has joined #pypy-sync - Jul 14 13:07:53 hi - Jul 14 13:07:56 stakkars: hi christian, we are in activity reports already - Jul 14 13:08:03 last week: Nothing since Europython sprint - Jul 14 13:08:12 next week: astbuilder (parser/compiler) - Jul 14 13:08:18 here my three sentences: - Jul 14 13:08:19 I have worked on long math and strutil and continued on seed 49 - Jul 14 13:08:19 I want to work on seed 49 next week - Jul 14 13:08:19 main blocker is windows, and I cannot use the fork thing. - Jul 14 13:08:25 blockers: nothing in particular - Jul 14 13:08:30 last week: work on providing translatable ast builder - Jul 14 13:08:30 next week: try and finish it - Jul 14 13:08:30 blockers: none - Jul 14 13:08:54 last week: vacation - Jul 14 13:09:11 next week: weakref, ? - Jul 14 13:09:20 blocks : none - Jul 14 13:09:53 * stakkars is sorry to be late, the machine decided to run a windows update right now :-( - Jul 14 13:10:02 ludal: you are going to post? - Jul 14 13:10:13 stakkars: what is "seed 49"? - Jul 14 13:10:19 Last week: Fixing some problems related to unicode, Work on annotation/rtyper to be able to process PyPy - Jul 14 13:10:28 Next week: annotation/rtyper and/or implementing modules os and math, if there is enough time take the week off. - Jul 14 13:10:41 Blockers: Not knowing the darker corners of the annotator/rtyper (In the process of being solved through having Samuele close by) - Jul 14 13:10:55 arre: take the week of from Strakt you mean? - Jul 14 13:10:57 hpk: post? - Jul 14 13:11:02 :-) there is a random shuffling algo in the annotator, and I got seed 49 - Jul 14 13:11:09 ludal: forget it, i missed your lines, sorry - Jul 14 13:11:22 stakkars: ah fine :-) - Jul 14 13:11:27 Yes. I have woked too many hours as it is. - Jul 14 13:11:46 ok, we got it then for now. Next topic: re-assigning/resolving - Jul 14 13:12:01 it seems that only aleale doesn't have a plan for next week - Jul 14 13:12:15 i think that weakref is not a priority and we should wait a bit with cfbolz's work on GC - Jul 14 13:12:15 right - Jul 14 13:12:26 wanted to say the same :-) - Jul 14 13:12:33 indeed - Jul 14 13:12:58 aleale: let's discuss possible work areas for you this off this pypy-sync meeting with Samuele and maybe others - Jul 14 13:13:08 ok - Jul 14 13:13:10 generally i'd like to be signalled ahead of the meeting if one doesn't know what to work on - Jul 14 13:13:29 next topic: - fixating sprint in Hildesheim (25th-31st July) - Jul 14 13:13:45 you probably all have read that the technical board thinks we should do a in-between internal sprint - Jul 14 13:13:56 the idea is 25th-31st July in Hildesheim (at my house) - Jul 14 13:14:15 who could come and who could not come? please everybody post here - Jul 14 13:14:19 yes, I thought this was decided, already - Jul 14 13:14:39 I can, minus one day - Jul 14 13:14:39 I will order my ticket, today - Jul 14 13:14:39 I won't come - Jul 14 13:14:57 yes, need to organize travel - Jul 14 13:15:01 can't: vacation - Jul 14 13:15:05 My vacation starts that week, so no. - Jul 14 13:15:20 I am not sure yet, just learned about it yesterday - Jul 14 13:15:27 what about arigo, is he traveling right now? - Jul 14 13:15:32 armin is going to come - Jul 14 13:15:36 will know tomorrow - Jul 14 13:15:37 he will be there - Jul 14 13:15:57 ok, that means: samuele, christian, holger, armin fulltime and cfbolz (-1 day) - Jul 14 13:15:58 I asked why he is not in themeeting. - Jul 14 13:16:09 he is busy, but he sent me mail with his info before - Jul 14 13:16:22 he is in belgium - Jul 14 13:16:43 then will be in D?sseldorf and from there to the sprint - Jul 14 13:16:57 thanks - Jul 14 13:17:15 for the sprint, we need an even number of people, as I remember :-) - Jul 14 13:17:16 ok, so the 25th-31st sprint is fixed then and i will prepare it, please arrive on the 24th evening or 25th morning and mail me about accomodation wishes - Jul 14 13:17:42 i'll post some info on pypy-sprint, make sure you are subscribed there - Jul 14 13:18:01 next topic: usage of issue tracker - Jul 14 13:18:25 for the upcoming releases (0.6.2 and 0.7/1.0) it has been discussed that we want to use the issue tracker - Jul 14 13:18:43 it should be clear to everyone (e.g. regarding the parser issues) that it is neccessary to look there - Jul 14 13:18:55 and update the issues accordingly - Jul 14 13:19:12 also the longobject issues etc.pp. - Jul 14 13:19:32 does everyone agree about using the pypy-dev tracker in this way? - Jul 14 13:19:41 ye - Jul 14 13:19:43 s - Jul 14 13:19:54 yes - Jul 14 13:20:05 yes - Jul 14 13:20:09 yes - Jul 14 13:20:19 yes - Jul 14 13:20:42 yes - Jul 14 13:20:51 pedronis: you too, i guess? - Jul 14 13:21:05 * hpk notes we have 9 minutes left - Jul 14 13:21:14 yes - Jul 14 13:21:23 next topic: - list current main areas of work regarding reaching Deliverable D05.2 - Jul 14 13:21:30 armin sent me this info from his POV: - Jul 14 13:21:39 Progressing on translate_pypy.py. There is a temp file - Jul 14 13:21:39 pypy/translator/goal/ISSUES.txt. Difficult to know more precisely what - Jul 14 13:21:39 is left. AFAICT we'll reach the first goal (PyPy as C ext module) any - Jul 14 13:21:39 day or week now. - Jul 14 13:22:08 samuele, anything you'd like to add (if not now then just to ISSUES.txt) - Jul 14 13:22:50 we are solving issues as we seen them fromt translate_pypy - Jul 14 13:22:58 there are 14000 blocks to go - Jul 14 13:23:09 we reach some hundreds now - Jul 14 13:23:16 oops - Jul 14 13:23:27 well, it doesn't mean much - Jul 14 13:23:46 each fix should adress more than one block - Jul 14 13:23:55 much more - Jul 14 13:24:13 pedronis: ok, i suggest to add separatable issues into the ISSUES.txt for everyone to see (if they are not solved/solveable isntantly) - Jul 14 13:24:15 the only worry is a bit memory usage but hard to tell until we go trough more blocks - Jul 14 13:24:28 any way we could parallelize the work ? - Jul 14 13:24:37 yes. - Jul 14 13:24:45 pedronis, stakkars: can you quickly tell about the "seed" situation? - Jul 14 13:24:59 pick a random seed not in (42, 49, samuele what's your's?) - Jul 14 13:25:18 46 - Jul 14 13:25:22 set the environ variable (wait...) - Jul 14 13:25:28 RTYPERSEED - Jul 14 13:25:41 let's put this info into ISSUES.txt please, stakkars, can you do that? - Jul 14 13:25:43 yep! And this gives you a different order of problems. - Jul 14 13:25:49 sure - Jul 14 13:25:55 ok, next topic (5 minutes left) - Jul 14 13:26:03 4 - Jul 14 13:26:07 Heidelberg sprint planning status (now: 15-22th August !!!) - Jul 14 13:26:16 why did the date change? - Jul 14 13:26:25 you mailed the 15th-22nd august for the sprint-date - Jul 14 13:26:29 in your last mail to me - Jul 14 13:26:31 hum - Jul 14 13:26:43 you are the person who needs to reserve the rooms :-) - Jul 14 13:26:58 Bad timing. My vacation ends 21/8. - Jul 14 13:27:11 it doesn't matter much for the rooms, I think I did a mistake in the mail to you :-( - Jul 14 13:27:16 sorry for the confusion - Jul 14 13:27:25 (I can get a room for the whole of August) - Jul 14 13:27:59 cfbolz: ok, so it stays 22nd (monday) -29th August (monday) ? - Jul 14 13:28:07 I have a fixed date on 24.09. in Kiel and on 27.08., everything else is fine. - Jul 14 13:28:18 hpk: I guess so - Jul 14 13:28:29 cfbolz: let's fix it until monday next week - Jul 14 13:28:34 is that possible for you? - Jul 14 13:28:46 I can fix it immediately, I just have to know - Jul 14 13:28:50 stakkars: the 27th August would be in the sprint, but maybe you can just travel a day? - Jul 14 13:29:30 for me it's fine 22-29 aug - Jul 14 13:29:41 ludal: great! - Jul 14 13:29:43 yes, I have to go to a big party, my ex-wife becomes 50 - Jul 14 13:29:50 aleale, arre, pedronis: for you it's fine as well i guess - Jul 14 13:29:57 yes - Jul 14 13:30:01 I am happy with the 22-29 too - Jul 14 13:30:13 all fine with me - Jul 14 13:30:14 i am going to contact Michael Hudson - Jul 14 13:30:19 Would work. - Jul 14 13:30:22 great, this finishes this meeting! - Jul 14 13:30:31 thanks for coming, see you next week latest! Modified: pypy/extradoc/minute/pypy-sync-07-21-2005.txt ============================================================================== --- pypy/extradoc/minute/pypy-sync-07-21-2005.txt (original) +++ pypy/extradoc/minute/pypy-sync-07-21-2005.txt Wed Aug 3 19:19:14 2005 @@ -2,7 +2,8 @@ pypy-sync developer meeting 21st July 2005 ============================================= -Attendees: Anders Chrigstroem, Samuele Pedroni, Adrien Di Mascio, +Attendees: + Anders Chrigstroem, Samuele Pedroni, Adrien Di Mascio, Ludovic Aubry, Carl Friedrich Bolz, Holger Krekel (minutes), Richard Emslie (partly) From rxe at codespeak.net Wed Aug 3 21:37:35 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 3 Aug 2005 21:37:35 +0200 (CEST) Subject: [pypy-svn] r15575 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050803193735.6DA5A27B73@code1.codespeak.net> Author: rxe Date: Wed Aug 3 21:37:33 2005 New Revision: 15575 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/structnode.py Log: Minor mods to pbs to make more llvm code more readable. Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Wed Aug 3 21:37:33 2005 @@ -118,18 +118,20 @@ p, c = lltype.parentlink(self.value) if p is not None: - assert False, "XXX TODO - but needed by rtyper" + assert False, "XXX TODO - but NOT needed by rtyper" return ref def get_pbcref(self, toptr): ref = self.ref p, c = lltype.parentlink(self.value) if p is not None: - assert False, "XXX TODO - but needed by rtyper" + assert False, "XXX TODO - but NOT needed by rtyper" fromptr = "%s*" % self.get_typerepr() - refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref) - ref = "cast(%s %s to %s)" % (fromptr, refptr, toptr) + # XXX old version + #refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref) + #ref = "cast(%s %s to %s)" % (fromptr, refptr, toptr) + ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) return ref def get_childref(self, index): @@ -171,7 +173,7 @@ item_length = len(items) if item_length == 0 or items[-1] != chr(0): items = items + [chr(0)] - l = item_length + 1 + item_length += 1 s = [] for c in items: if ord(c) in StrArrayNode.printables: @@ -180,7 +182,7 @@ s.append("\\%02x" % ord(c)) r = 'c"%s"' % "".join(s) - return l, r + return item_length, r class VoidArrayNode(ConstantLLVMNode): Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Wed Aug 3 21:37:33 2005 @@ -139,7 +139,7 @@ node = StructNode(self, value) elif isinstance(type_, lltype.Array): - if type_ is STR.chars: + if type_.OF is lltype.Char: node = StrArrayNode(self, value) elif type_.OF is lltype.Void: node = VoidArrayNode(self, value) Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Wed Aug 3 21:37:33 2005 @@ -218,7 +218,7 @@ ref = self.ref p, c = lltype.parentlink(self.value) if p is not None: - assert False, "XXX TODO" + assert False, "XXX TODO - but NOT needed by rtyper" fromptr = "%s*" % self.get_typerepr() refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref) From pedronis at codespeak.net Wed Aug 3 21:53:50 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 3 Aug 2005 21:53:50 +0200 (CEST) Subject: [pypy-svn] r15576 - pypy/dist/pypy/annotation Message-ID: <20050803195350.A1A3327B73@code1.codespeak.net> Author: pedronis Date: Wed Aug 3 21:53:49 2005 New Revision: 15576 Modified: pypy/dist/pypy/annotation/classdef.py Log: follow up to r11953 to deal with multimethods attaching methods while annotating. r11953 assumption was that this would result in a matching with no uplookup match, but this is not the case if subclasses share a same impl function because this result in matching receiving a unified PBC with the impl function attached to a superclass classdef resulting in a possibly successfull uplookup match. Double-check in that case that uplookup classdef was considered as possible source for the impl function, otherwise look for possible missing definitions for the attribute. Now annotation terminates with query.sanity_check_for_methods not displaying any problem. Modified: pypy/dist/pypy/annotation/classdef.py ============================================================================== --- pypy/dist/pypy/annotation/classdef.py (original) +++ pypy/dist/pypy/annotation/classdef.py Wed Aug 3 21:53:49 2005 @@ -177,6 +177,7 @@ def add_source_for_attribute(self, attr, source, clsdef=None): """Adds information about a constant source for an attribute. """ + sources = self.attr_sources.setdefault(attr, {}) for cdef in self.getmro(): if attr in cdef.attrs: # the Attribute() exists already for this class (or a parent) @@ -191,7 +192,6 @@ return else: # remember the source in self.attr_sources - sources = self.attr_sources.setdefault(attr, {}) sources[source] = clsdef # register the source in any Attribute found in subclasses, # to restore invariant (III) @@ -327,6 +327,7 @@ uplookup = None upfunc = None meth = False + check_for_missing_attrs = False for func, value in pbc.prebuiltinstances.items(): if isclassdef(value): meth = True @@ -342,14 +343,27 @@ else: continue # not matching d[func] = value - if uplookup is not None: + if uplookup is not None: + # hack^2, in this case the classdef for uplookup could be the result + # of the union of subclass sources that share the same implementation function + # so there could be still super and subclass implementations added after the fact + # that could be going undetected. We use uplookup.attr_sources[name] to flag + # whether a super implementation was considered and as such not undetected + if name is not None and not name in uplookup.attr_sources: + uplookup.attr_sources.setdefault(name, {}) + check_for_missing_attrs = True + # when the method is found in a parent class, it get bound to the # 'self' subclass. This allows the 'func: classdef' entry of the # PBC dictionary to track more precisely with which 'self' the # method is called. d[upfunc] = self elif meth and name is not None: + check_for_missing_attrs = True + + if check_for_missing_attrs: self.check_missing_attribute_update(name) + if d: return SomePBC(d) else: From pedronis at codespeak.net Wed Aug 3 22:21:20 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 3 Aug 2005 22:21:20 +0200 (CEST) Subject: [pypy-svn] r15577 - pypy/dist/pypy/translator/goal Message-ID: <20050803202120.BD85627B83@code1.codespeak.net> Author: pedronis Date: Wed Aug 3 22:21:19 2005 New Revision: 15577 Modified: pypy/dist/pypy/translator/goal/query.py pypy/dist/pypy/translator/goal/translate_pypy.py Log: add sanity checking for method defs annotation Modified: pypy/dist/pypy/translator/goal/query.py ============================================================================== --- pypy/dist/pypy/translator/goal/query.py (original) +++ pypy/dist/pypy/translator/goal/query.py Wed Aug 3 22:21:19 2005 @@ -462,6 +462,7 @@ meths.append(attr) if meths: withmeths.append((clsdef, meths)) + lost = 0 for clsdef, meths in withmeths: cls = clsdef.cls n = 0 @@ -476,5 +477,6 @@ f = subcls.cls.__dict__.get(name) if f: if f not in funcs: - print name, subcls.cls, cls, subcls.attrs.keys() - + print "Lost method!", name, subcls.cls, cls, subcls.attrs.keys() + lost += 0 + return lost Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Wed Aug 3 22:21:19 2005 @@ -80,6 +80,8 @@ # catch TyperError to allow for post-mortem dump from pypy.rpython.error import TyperError +from pypy.translator.goal import query + # XXX this tries to make compiling faster from pypy.translator.tool import cbuild cbuild.enable_fast_compilation() @@ -107,6 +109,9 @@ print 'Annotating...' a = t.annotate(inputtypes, policy=PyPyAnnotatorPolicy()) sanity_check_exceptblocks(t) + lost = query.sanity_check_methods(t) + assert not lost, "lost methods, something gone wrong with the annotation of method defs" + print "*** No lost method defs." worstblocks_topten(a, 3) find_someobjects(t) if a: #and not options['-no-s']: From ericvrp at codespeak.net Wed Aug 3 22:38:12 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 22:38:12 +0200 (CEST) Subject: [pypy-svn] r15578 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050803203812.C4C5527B84@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 22:38:11 2005 New Revision: 15578 Modified: pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: Some refactoring to move more exception handling code together. One more exception test. Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Wed Aug 3 22:38:11 2005 @@ -122,7 +122,8 @@ self.write_block_operations(codewriter, block) self.write_block_branches(codewriter, block) - def write_block_phi_nodes(self, codewriter, block): + def get_phi_data(self, block): + data = [] entrylinks = mkentrymap(self.graph)[block] entrylinks = [x for x in entrylinks if x.prevblock is not None] inputargs = self.db.repr_arg_multi(block.inputargs) @@ -135,13 +136,13 @@ if link.prevblock.exitswitch == Constant(last_exception) and \ link.prevblock.exits[0].target != block: blocknames[i] += '_exception_found_branchto_' + self.block_to_name[block] + data.append( (arg, type_, names, blocknames) ) + return data + + def write_block_phi_nodes(self, codewriter, block): + for arg, type_, names, blocknames in self.get_phi_data(block): if type_ != "void": - if arg.startswith('%last_exc_value_') and type_ == '%structtype.object*': - e = self.db._translator.rtyper.getexceptiondata() - lltype_of_exception_value = ('%structtype.' + e.lltype_of_exception_value.TO.__name__ + '*') - codewriter.load(arg, lltype_of_exception_value, '%last_exception_value') - else: - codewriter.phi(arg, type_, names, blocknames) + codewriter.phi(arg, type_, names, blocknames) def write_block_branches(self, codewriter, block): #assert len(block.exits) <= 2 #more exits are possible (esp. in combination with exceptions) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 3 22:38:11 2005 @@ -260,6 +260,9 @@ lltype_of_exception_type = ('%structtype.' + e.lltype_of_exception_type.TO.__name__ + '*') + lltype_of_exception_value = ('%structtype.' + + e.lltype_of_exception_value.TO.__name__ + + '*') self.codewriter.label(exc_label) @@ -269,11 +272,24 @@ etype = self.db.obj2node[link.llexitcase._obj] current_exception_type = etype.get_ref() - #self.codewriter.comment('etype=%s, current_exception_type=%s' % (str(etype.ref), str(current_exception_type))) target = self.node.block_to_name[link.target] exc_found_label = block_label + '_exception_found_branchto_' + target - exc_found_labels.append( (exc_found_label, target) ) + last_exc_type_var, last_exc_value_var = None, None + + for p in self.node.get_phi_data(link.target): + arg, type_, names, blocknames = p + for name, blockname in zip(names, blocknames): + if blockname != exc_found_label: + continue + #XXX might want to refactor the next few lines + if name.startswith('%last_exception_'): + last_exc_type_var = name + if name.startswith('%last_exc_value_'): + last_exc_value_var = name + + t = (exc_found_label,target,last_exc_type_var,last_exc_value_var) + exc_found_labels.append(t) not_this_exception_label = block_label + '_not_exception_' + etype.ref[1:] @@ -297,8 +313,13 @@ self.codewriter.comment('reraise when exception is not caught') self.codewriter.unwind() - for label, target in exc_found_labels: + for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: self.codewriter.label(label) + if last_exc_type_var: + self.codewriter.load(last_exc_type_var, lltype_of_exception_type, '%last_exception_type') + if last_exc_value_var: + self.codewriter.load(last_exc_value_var, lltype_of_exception_value, '%last_exception_value') + self.codewriter.br_uncond(target) def malloc(self, op): Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Wed Aug 3 22:38:11 2005 @@ -116,12 +116,11 @@ py.test.raises(Exception, "f(10)") def test_reraise2(): - py.test.skip("PyPy interpreter not happy with this test") def fn(n): lst = range(10) try: getitem(lst,n) - except e: + except Exception, e: raise e return 4 f = compile_function(fn, [int]) From ericvrp at codespeak.net Wed Aug 3 22:40:59 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 22:40:59 +0200 (CEST) Subject: [pypy-svn] r15579 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050803204059.DB6FF27B88@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 22:40:59 2005 New Revision: 15579 Modified: pypy/dist/pypy/translator/llvm2/database.py Log: minor cleanup Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Wed Aug 3 22:40:59 2005 @@ -280,11 +280,6 @@ return 'null' else: return node.get_ref() - - # XXX ??? dont understand rxe ??? - #XXX related to llvm2/test/test_genllvm/test_dict_creation - #XXX "v962 = same_as((<* None>))" - #XXX this <* None> gets propagated to the next block and fails at the phi node! else: assert isinstance(arg, Variable) return "%" + str(arg) From ericvrp at codespeak.net Wed Aug 3 22:57:12 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 3 Aug 2005 22:57:12 +0200 (CEST) Subject: [pypy-svn] r15580 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050803205712.A4B4E27B8B@code1.codespeak.net> Author: ericvrp Date: Wed Aug 3 22:57:12 2005 New Revision: 15580 Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: llvm rem (float mod) was implemented incorrect. After communication with llvm people they fixed it in llvm cvs (untested by me) see: http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=611 Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Wed Aug 3 22:57:12 2005 @@ -211,7 +211,8 @@ # floats def test_float_operations(): - py.test.skip("llvm rem operation doesnt seem to work...") + py.test.skip("llvm rem operation doesnt seem to work...fixed in llvm cvs") + #see: http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=611 def func(x, y): z = x + y / 2.1 * x z = z % 60.0 From pedronis at codespeak.net Wed Aug 3 23:00:03 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 3 Aug 2005 23:00:03 +0200 (CEST) Subject: [pypy-svn] r15581 - pypy/dist/pypy/objspace/std Message-ID: <20050803210003.3BCF027B8D@code1.codespeak.net> Author: pedronis Date: Wed Aug 3 23:00:02 2005 New Revision: 15581 Modified: pypy/dist/pypy/objspace/std/model.py Log: reenabled marshal_w multimethod definitions, it was innocent Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Wed Aug 3 23:00:02 2005 @@ -53,9 +53,8 @@ from pypy.objspace.std import dictproxyobject from pypy.objspace.std import fake import pypy.objspace.std.default # register a few catch-all multimethods - # XXX the following line causes 5 RTyper errors - # related to the marshal multimethod - #import pypy.objspace.std.marshal_impl # install marshal multimethods + + import pypy.objspace.std.marshal_impl # install marshal multimethods # the set of implementation types self.typeorder = { From pedronis at codespeak.net Thu Aug 4 03:52:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 03:52:59 +0200 (CEST) Subject: [pypy-svn] r15582 - in pypy/dist/pypy: annotation rpython rpython/test translator/c/test Message-ID: <20050804015259.5E57727B5B@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 03:52:53 2005 New Revision: 15582 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/unaryop.py pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/rclass.py pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/rpython/test/test_rclass.py pypy/dist/pypy/translator/c/test/test_typed.py Log: issue106 in-progress added support (with some tests) to annotation+rtyper to express identity hashes using hash() for rpython class instances. The hash value when necessary is preserved across translation for pre-built instances Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Thu Aug 4 03:52:53 2005 @@ -195,6 +195,8 @@ self.pbc_call_sites = {} + self.needs_hash_support = {} + self.memo_tables = [] self.stats = Stats(self) @@ -230,6 +232,12 @@ self.consider_pbc_call(pbc, shape, spaceop) self.pbc_call_sites = {} + for cls in self.needs_hash_support.keys(): + for cls2 in self.needs_hash_support: + if issubclass(cls, cls2) and cls is not cls2: + del self.needs_hash_support[cls] + break + def getclassdef(self, cls): """Get the ClassDef associated with the given user cls.""" if cls is object: Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Thu Aug 4 03:52:53 2005 @@ -81,7 +81,7 @@ return obj.is_true() def hash(obj): - return SomeInteger() + raise TypeError, "hash() is not generally supported" def str(obj): getbookkeeper().count('str', obj) @@ -322,6 +322,9 @@ def ord(str): return SomeInteger(nonneg=True) + def hash(str): + return SomeInteger() + def method_split(str, patt): # XXX getbookkeeper().count("str_split", str, patt) return getbookkeeper().newlist(SomeString()) @@ -393,6 +396,10 @@ # create or update the attribute in clsdef clsdef.generalize_attr(attr, s_value) + def hash(ins): + getbookkeeper().needs_hash_support[ins.classdef.cls] = True + return SomeInteger() + class __extend__(SomeBuiltin): def simple_call(bltn, *args): Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Aug 4 03:52:53 2005 @@ -4,7 +4,7 @@ from pypy.rpython.rarithmetic import intmask, r_uint, ovfcheck import py from pypy.rpython.lltype import _ptr, Ptr, Void, typeOf, malloc, cast_pointer, PyObject, pyobjectptr -from pypy.rpython.lltype import Array +from pypy.rpython.lltype import Array, Struct from pypy.rpython.rmodel import getfunctionptr import math @@ -297,6 +297,14 @@ assert isinstance(ptr1, _ptr) return not bool(ptr1) + def op_cast_ptr_to_int(self, ptr1): # xxx should this logic migrate to lltype _ptr itself? + assert isinstance(ptr1, _ptr) + assert isinstance(typeOf(ptr1).TO, (Array, Struct)) + obj = ptr1._obj + while obj._parentstructure(): + obj = obj._parentstructure() + return id(obj) + def op_cast_int_to_float(self, i): assert type(i) is int return float(i) Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Thu Aug 4 03:52:53 2005 @@ -8,7 +8,7 @@ from pypy.rpython.lltype import cast_pointer, castable, nullptr from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo, typeOf from pypy.rpython.lltype import Array, Char, Void, attachRuntimeTypeInfo -from pypy.rpython.lltype import FuncType, Bool +from pypy.rpython.lltype import FuncType, Bool, Signed # # There is one "vtable" per user class, with the following structure: @@ -377,6 +377,12 @@ fields[name] = mangled_name, r llfields.append((mangled_name, r.lowleveltype)) # + # hash() support + if self.rtyper.needs_hash_support(self.classdef.cls): + from pypy.rpython import rint + fields['_hash_cache_'] = 'hash_cache', rint.signed_repr + llfields.append(('hash_cache', Signed)) + self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef) self.rbase.setup() object_type = GcStruct(self.classdef.cls.__name__, @@ -434,6 +440,8 @@ for name, (mangled_name, r) in self.fields.items(): if r.lowleveltype == Void: llattrvalue = None + elif name == '_hash_cache_': # hash() support + llattrvalue = hash(value) else: try: attrvalue = getattr(value, name) @@ -520,6 +528,15 @@ vinst, = hop.inputargs(self) return self.getfield(vinst, '__class__', hop.llops) + def rtype_hash(self, hop): + if self.classdef is None: + raise TyperError, "hash() not supported for this class" + if self.rtyper.needs_hash_support( self.classdef.cls): + vinst, = hop.inputargs(self) + return hop.gendirectcall(ll_inst_hash, vinst) + else: + return self.rbase.rtype_hash(hop) + def rtype_getattr(self, hop): attr = hop.args_s[1].const vinst, vattr = hop.inputargs(self, Void) @@ -634,3 +651,9 @@ def ll_runtime_type_info(obj): return obj.typeptr.rtti + +def ll_inst_hash(ins): + cached = ins.hash_cache + if cached == 0: + cached = ins.hash_cache = id(ins) + return cached Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Thu Aug 4 03:52:53 2005 @@ -458,6 +458,9 @@ # __________ utilities __________ + def needs_hash_support(self, cls): + return cls in self.annotator.bookkeeper.needs_hash_support + def getfunctionptr(self, graphfunc): def getconcretetype(v): return self.bindingrepr(v).lowleveltype Modified: pypy/dist/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rclass.py (original) +++ pypy/dist/pypy/rpython/test/test_rclass.py Thu Aug 4 03:52:53 2005 @@ -1,7 +1,7 @@ from pypy.translator.translator import Translator from pypy.rpython.lltype import * from pypy.rpython.test.test_llinterp import interpret - +from pypy.rpython.rarithmetic import intmask class EmptyBase(object): pass @@ -282,3 +282,21 @@ assert res == ~0x0100 & 0x3ff res = interpret(f, [3]) assert res == ~0x0200 & 0x3ff + +def test_hash_preservation(): + class C: + pass + class D(C): + pass + c = C() + d = D() + def f(): + d2 = D() + x = hash(d2) == id(d2) # xxx check for this CPython peculiarity for now + return x, hash(c)+hash(d) + + res = interpret(f, []) + + assert res.item0 == True + assert res.item1 == intmask(hash(c)+hash(d)) + Modified: pypy/dist/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_typed.py (original) +++ pypy/dist/pypy/translator/c/test/test_typed.py Thu Aug 4 03:52:53 2005 @@ -305,3 +305,24 @@ for value in range(15): i = r_uint(value) assert f(i) == fn(i) + + def test_hash_preservation(self): + class C: + pass + class D(C): + pass + c = C() + d = D() + def fn(): + d2 = D() + x = hash(d2) == id(d2) # xxx check for this CPython peculiarity for now + return x, hash(c)+hash(d) + + f = self.getcompiled(fn) + + res = f() + + from pypy.rpython.rarithmetic import intmask + + assert res[0] == True + assert res[1] == intmask(hash(c)+hash(d)) From pedronis at codespeak.net Thu Aug 4 03:56:36 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 03:56:36 +0200 (CEST) Subject: [pypy-svn] r15583 - in pypy/dist/pypy: interpreter objspace objspace/std Message-ID: <20050804015636.C753627B5B@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 03:56:31 2005 New Revision: 15583 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/objspace/descroperation.py pypy/dist/pypy/objspace/std/objecttype.py Log: issue106 in-progress start of refactoring of the implementation of identity hash computation. Use the rtyper support for hash() and value preservation across translation. This is a first stab. By attaching a identity_hash using hash() only where stricly necessary we can avoid all W_Root object to internally grow an hash_cache field: this rearragement is to be done later. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Aug 4 03:56:31 2005 @@ -5,7 +5,7 @@ from pypy.interpreter.pycompiler import PythonCompiler, PyPyCompiler from pypy.interpreter.miscutils import ThreadLocals from pypy.tool.cache import Cache -from pypy.rpython.rarithmetic import r_uint +from pypy.rpython.rarithmetic import r_uint, intmask __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable', 'W_Root'] @@ -59,6 +59,9 @@ def setslotvalue(self, index, w_val): raise NotImplementedError + def identity_hash(self, space): + return space.wrap(intmask(hash(self))) #space.id(self) + class BaseWrappable(W_Root): """A subclass of BaseWrappable is an internal, interpreter-level class that can nevertheless be exposed at application-level by space.wrap().""" Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Thu Aug 4 03:56:31 2005 @@ -269,7 +269,7 @@ space.lookup(w_obj, '__cmp__') is not None: raise OperationError(space.w_TypeError, space.wrap("unhashable type")) - return space.id(w_obj) + return w_obj.identity_hash(space) w_result = space.get_and_call_function(w_hash, w_obj) if space.is_true(space.isinstance(w_result, space.w_int)): return w_result Modified: pypy/dist/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/objecttype.py (original) +++ pypy/dist/pypy/objspace/std/objecttype.py Thu Aug 4 03:56:31 2005 @@ -53,7 +53,7 @@ return w_obj def descr__hash__(space, w_obj): - return space.id(w_obj) + return w_obj.identity_hash(space) def descr__init__(space, w_obj, __args__): pass From hpk at codespeak.net Thu Aug 4 09:22:55 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 4 Aug 2005 09:22:55 +0200 (CEST) Subject: [pypy-svn] r15584 - pypy/dist/pypy/documentation/website Message-ID: <20050804072255.2C06027B5B@code1.codespeak.net> Author: hpk Date: Thu Aug 4 09:22:54 2005 New Revision: 15584 Modified: pypy/dist/pypy/documentation/website/news.txt Log: finalizing the hildesheim2 sprint item, added some more pictures from sunday. Modified: pypy/dist/pypy/documentation/website/news.txt ============================================================================== --- pypy/dist/pypy/documentation/website/news.txt (original) +++ pypy/dist/pypy/documentation/website/news.txt Thu Aug 4 09:22:54 2005 @@ -24,27 +24,25 @@ .. _`Heidelberg sprint announcement`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/Heidelberg-sprint.html -PyPy Hildesheim2 sprint ongoing ... -====================================================== +PyPy Hildesheim2 finished: first self-contained PyPy run! +=========================================================== -Up until 31st August we are in a PyPy sprint at `Trillke-Gut`_. +Up until 31st August we were in a PyPy sprint at `Trillke-Gut`_. Carl has written a `report about day 1`_, Holger -about `day 2 and day 3`_ and Carl again about `day 4 and day 5`_. -We also have some `pictures from the sprint`_. -There has been some great progress already in that we now succeed -to fully annotate the PyPy code base and have a mode where -we don't borrow object implementations from CPython anymore -(which of course means that we have some modules missing). -On `day 6`_ we finally had a `breakthrough`_: PyPy runs -on its own! Hurray_!. +about `day 2 and day 3`_ and Carl again about `day 4 and day 5`_, +On `day 6`_ Holger reports the `breakthrough`_: PyPy runs +on its own! Hurray_!. And Carl finally reports about the winding +down of `day 7`_ which saw us relaxing, discussing and generally +having a good time. You might want to look at the selected +`pictures from the sprint`_. .. _`report about day 1`: http://codespeak.net/pipermail/pypy-dev/2005q3/002217.html .. _`day 2 and day 3`: http://codespeak.net/pipermail/pypy-dev/2005q3/002220.html .. _`day 4 and day 5`: http://codespeak.net/pipermail/pypy-dev/2005q3/002234.html .. _`day 6`: http://codespeak.net/pipermail/pypy-dev/2005q3/002239.html -.. _`breakthrough`: http://codespeak.net/~hpk/hildesheim2-sprint-www/hildesheim2-sprint-www-Pages/Image35.html -.. _`hurray`: http://codespeak.net/~hpk/hildesheim2-sprint-www/hildesheim2-sprint-www-Pages/Image36.html - +.. _`day 7`: http://codespeak.net/pipermail/pypy-dev/2005q3/002245.html +.. _`breakthrough`: http://codespeak.net/~hpk/hildesheim2-sprint-www/hildesheim2-sprint-www-Thumbnails/36.jpg +.. _`hurray`: http://codespeak.net/~hpk/hildesheim2-sprint-www/hildesheim2-sprint-www-Pages/Image37.html .. _`pictures from the sprint`: http://codespeak.net/~hpk/hildesheim2-sprint-www/ .. _`Trillke-Gut`: http://www.trillke.net/images/HomePagePictureSmall.jpg From arigo at codespeak.net Thu Aug 4 09:34:22 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 09:34:22 +0200 (CEST) Subject: [pypy-svn] r15585 - in pypy/dist/pypy/rpython: . module/test Message-ID: <20050804073422.9ADD927B5B@code1.codespeak.net> Author: arigo Date: Thu Aug 4 09:34:21 2005 New Revision: 15585 Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/test/test_ll_os_path.py Log: Test the os.path functions used in PyPy: join() and isdir(). Testing both ntpath.join() and posixpath.join(). Hackish fix for ntpath.join(). Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Thu Aug 4 09:34:21 2005 @@ -109,3 +109,13 @@ for name in simple_math_functions: declare(getattr(math, name), float, 'll_math/%s' % name) + +# ___________________________________________________________ +# win/NT hack: patch ntpath.isabs() to be RPythonic + +import ntpath +def isabs(s): + """Test whether a path is absolute""" + s = ntpath.splitdrive(s)[1] + return s != '' and s[0] in '/\\' +ntpath.isabs = isabs Modified: pypy/dist/pypy/rpython/module/test/test_ll_os_path.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_os_path.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_os_path.py Thu Aug 4 09:34:21 2005 @@ -4,9 +4,37 @@ from pypy.rpython.module.ll_os_path import * from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy +from pypy.rpython.test.test_llinterp import interpret +from pypy.tool.udir import udir def test_exists(): filename = to_rstr(str(py.magic.autopath())) assert ll_os_path_exists(filename) == True assert not ll_os_path_exists(to_rstr( "strange_filename_that_looks_improbable.sde")) + +def test_posixpath(): + import posixpath + def f(): + assert posixpath.join("/foo", "bar") == "/foo/bar" + assert posixpath.join("/foo", "spam/egg") == "/foo/spam/egg" + assert posixpath.join("/foo", "/bar") == "/bar" + interpret(f, []) + +def test_ntpath(): + import ntpath + def f(): + assert ntpath.join("\\foo", "bar") == "\\foo\\bar" + assert ntpath.join("c:\\foo", "spam\\egg") == "c:\\foo\\spam\\egg" + assert ntpath.join("c:\\foo", "d:\\bar") == "d:\\bar" + interpret(f, []) + +def test_isdir(): + s = str(udir.join('test_isdir')) + def f(): + return os.path.isdir(s) + res = interpret(f, []) + assert res == os.path.isdir(s) + os.mkdir(s) + res = interpret(f, []) + assert res is True From hpk at codespeak.net Thu Aug 4 09:38:28 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 4 Aug 2005 09:38:28 +0200 (CEST) Subject: [pypy-svn] r15586 - pypy/extradoc/sprintinfo Message-ID: <20050804073828.0E52627B62@code1.codespeak.net> Author: hpk Date: Thu Aug 4 09:38:27 2005 New Revision: 15586 Modified: pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt pypy/extradoc/sprintinfo/heidelberg-people.txt Log: fix ReST + my planned heidelberg time Modified: pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt ============================================================================== --- pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt (original) +++ pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt Thu Aug 4 09:38:27 2005 @@ -26,7 +26,7 @@ filed as issues -------------- +----------------- - rtyper problem: exceptions are no longer always at the end of a code block because of the lowlevel rewriting Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 4 09:38:27 2005 @@ -16,7 +16,7 @@ Carl Friedrich Bolz 21st-29th Aug ? Niklaus Haldimann 21st-29th Aug private Eric van Riet Paap 22nd-28th Aug private -Holger Krekel 21st-29th Aug private +Holger Krekel 21st-28th Aug private Richard Emslie 22nd-29th Aug private Michael Hudson (?) ? ? Beatrice Duering ? ? From cfbolz at codespeak.net Thu Aug 4 09:51:09 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 4 Aug 2005 09:51:09 +0200 (CEST) Subject: [pypy-svn] r15587 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050804075109.9C96527B5B@code1.codespeak.net> Author: cfbolz Date: Thu Aug 4 09:51:09 2005 New Revision: 15587 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: remove some tests (not really useful) and fixed __setitem__. Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Thu Aug 4 09:51:09 2005 @@ -60,7 +60,7 @@ if isinstance(T, (lltype.Struct, lltype.Array)): return simulatorptr(lltype.Ptr(T), address) elif isinstance(T, lltype.Primitive): - return address._load(primitive_to_fmt[T]) + return address._load(primitive_to_fmt[T])[0] else: assert 0, "not implemented yet" @@ -145,14 +145,15 @@ if isinstance(T1, lltype.ContainerType): s = "cannot directly assign to container array items" raise TypeError, s - T2 = typeOf(val) + T2 = lltype.typeOf(value) if T2 != T1: raise TypeError("%r items:\n" "expect %r\n" " got %r" % (self._T, T1, T2)) if not (0 <= i < self._address.signed[0]): raise IndexError, "array index out of bounds" - self._address._store(get_layout(self._T.OF), value) + addr = self._address + self._layout[0] + i * self._layout[1] + addr._store(get_layout(self._T.OF), value) return raise TypeError("%r instance is not an array" % (self._T,)) Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Thu Aug 4 09:51:09 2005 @@ -175,35 +175,6 @@ p3 = p1b.sub.sub assert p1b == cast_pointer(lltype.Ptr(S1bis), p3) -def DONOTtest_best_effort_gced_parent_detection(): - S2 = lltype.Struct("s2", ('a', lltype.Signed)) - S1 = lltype.GcStruct("s1", ('sub1', S2), ('sub2', S2), - ('tail', lltype.Array(('e', lltype.Signed)))) - p1 = malloc(S1, 1) - p2 = p1.sub2 - assert p2.a == 0 - p3 = p1.tail - p3[0].e = 1 - assert p3[0].e == 1 - del p1 - import gc - gc.collect() - py.test.raises(RuntimeError, "p2.a") - py.test.raises(RuntimeError, "p3[0]") - -def DONOTtest_best_effort_gced_parent_for_arrays(): - A1 = lltype.GcArray(('v', lltype.Signed)) - p1 = malloc(A1, 10) - p1[5].v=3 - assert p1[0].v == 0 - assert p1[9].v == 0 - assert p1[5].v == 3 - p1_5 = p1[5] - del p1 - import gc - gc.collect() - py.test.raises(RuntimeError, "p1_5.v") - def DONOTtest_functions(): F = lltype.FuncType((Signed,), Signed) @@ -214,7 +185,6 @@ py.test.raises(TypeError, pf, 0, 0) py.test.raises(TypeError, pf, 'a') - def test_forward_reference(): F = lltype.GcForwardReference() S = lltype.GcStruct('abc', ('x', lltype.Ptr(F))) @@ -238,8 +208,7 @@ assert lltype.typeOf(p10) == lltype.Ptr(S1) assert not p10 - -def DONOTtest_array_with_non_container_elements(): +def test_array_with_non_container_elements(): As = lltype.GcArray(lltype.Signed) a = malloc(As, 3) assert a[0] == 0 @@ -250,11 +219,11 @@ S = lltype.GcStruct('s', ('x', lltype.Signed)) s = malloc(S) py.test.raises(TypeError, "a[1] = s") - S = lltype.GcStruct('s', ('x', lltype.Signed)) S = lltype.Struct('s', ('x', lltype.Signed)) A = lltype.GcArray(S) a = malloc(A, 2) - a[0] = malloc(S) + s = malloc(S) + py.test.raises(TypeError, "a[0] = s") def DONOTtest_immortal_parent(): S1 = GcStruct('substruct', ('x', Signed)) From hpk at codespeak.net Thu Aug 4 09:55:01 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 4 Aug 2005 09:55:01 +0200 (CEST) Subject: [pypy-svn] r15588 - pypy/dist/pypy/translator/goal Message-ID: <20050804075501.1758527B5B@code1.codespeak.net> Author: hpk Date: Thu Aug 4 09:55:00 2005 New Revision: 15588 Modified: pypy/dist/pypy/translator/goal/app_example.py Log: changed app_example.py to do 'import code ; code.interact()' basically. Modified: pypy/dist/pypy/translator/goal/app_example.py ============================================================================== --- pypy/dist/pypy/translator/goal/app_example.py (original) +++ pypy/dist/pypy/translator/goal/app_example.py Thu Aug 4 09:55:00 2005 @@ -1,3 +1,7 @@ -print '--- beginning of app_example.py ---' +print '--- beginning of PyPy run of app_example.py ---' print 6*7 -print '--- end of app_example.py ---' +print "OK, we managed to print a good number, now let's try 'import code'" +print "(this will last a while, because compiling happens at app-level)" +import code +print "fine, we managed to import 'code', now let's run code.interact()" +code.interact() From ale at codespeak.net Thu Aug 4 10:09:00 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 4 Aug 2005 10:09:00 +0200 (CEST) Subject: [pypy-svn] r15589 - pypy/dist/lib-python Message-ID: <20050804080900.44A5E27B5B@code1.codespeak.net> Author: ale Date: Thu Aug 4 10:08:59 2005 New Revision: 15589 Added: pypy/dist/lib-python/test_fails.txt Log: A list of why compliance tests fails. This list is not complete. Added: pypy/dist/lib-python/test_fails.txt ============================================================================== --- (empty file) +++ pypy/dist/lib-python/test_fails.txt Thu Aug 4 10:08:59 2005 @@ -0,0 +1,11 @@ +test_pprint fails because "dict.__repr__ is dict.__repr__" equals False + +test_import fails because os.open is case insensitive (at least on Mac os X) + +multiple tests fails because from __future__ import division does not work (true division is never enabled) + +test_iterlen fails because len is not implemented for SeqIter (and other structures like generators (reversed) ) + +test_compiler fails because of "maximum recursion depth exceeded" + +test_decorator fails because globals and locals are None in a nested function ? \ No newline at end of file From hpk at codespeak.net Thu Aug 4 10:13:09 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 4 Aug 2005 10:13:09 +0200 (CEST) Subject: [pypy-svn] r15591 - pypy/dist/lib-python Message-ID: <20050804081309.73BA927B5B@code1.codespeak.net> Author: hpk Date: Thu Aug 4 10:13:08 2005 New Revision: 15591 Added: pypy/dist/lib-python/failure_list.txt - copied, changed from r15590, pypy/dist/lib-python/test_fails.txt Removed: pypy/dist/lib-python/test_fails.txt Log: rename + some formatting Copied: pypy/dist/lib-python/failure_list.txt (from r15590, pypy/dist/lib-python/test_fails.txt) ============================================================================== --- pypy/dist/lib-python/test_fails.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 10:13:08 2005 @@ -1,11 +1,19 @@ -test_pprint fails because "dict.__repr__ is dict.__repr__" equals False +test_pprint + fails because "dict.__repr__ is dict.__repr__" equals False -test_import fails because os.open is case insensitive (at least on Mac os X) +test_import + fails because os.open is case insensitive (at least on Mac os X) -multiple tests fails because from __future__ import division does not work (true division is never enabled) +multiple tests fail because from __future__ import division does +not work (true division is never enabled) -test_iterlen fails because len is not implemented for SeqIter (and other structures like generators (reversed) ) +test_iterlen -test_compiler fails because of "maximum recursion depth exceeded" + fails because len is not implemented for SeqIter (and + other structures like generators (reversed) ) -test_decorator fails because globals and locals are None in a nested function ? \ No newline at end of file +test_compiler + fails because of "maximum recursion depth exceeded" + +test_decorator + fails because globals and locals are None in a nested function ? Deleted: /pypy/dist/lib-python/test_fails.txt ============================================================================== --- /pypy/dist/lib-python/test_fails.txt Thu Aug 4 10:13:08 2005 +++ (empty file) @@ -1,11 +0,0 @@ -test_pprint fails because "dict.__repr__ is dict.__repr__" equals False - -test_import fails because os.open is case insensitive (at least on Mac os X) - -multiple tests fails because from __future__ import division does not work (true division is never enabled) - -test_iterlen fails because len is not implemented for SeqIter (and other structures like generators (reversed) ) - -test_compiler fails because of "maximum recursion depth exceeded" - -test_decorator fails because globals and locals are None in a nested function ? \ No newline at end of file From cfbolz at codespeak.net Thu Aug 4 10:14:46 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 4 Aug 2005 10:14:46 +0200 (CEST) Subject: [pypy-svn] r15592 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050804081446.87DAF27B60@code1.codespeak.net> Author: cfbolz Date: Thu Aug 4 10:14:45 2005 New Revision: 15592 Modified: pypy/dist/pypy/rpython/memory/lladdress.py pypy/dist/pypy/rpython/memory/test/test_address.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: added possibility to attach real Python objects to an address (e.g. for function pointers and PyObjects). Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 4 10:14:45 2005 @@ -79,11 +79,35 @@ convert_from = Address convert_to = Address._getintattr +# used to attach some real python object to the address: +# for SomeObjects and Functions +class _attached_accessor(_accessor): + attached_objects = [] + object_to_number = {} + + format = "i" + size = struct.calcsize("i") + + def convert_from(self, i): + try: + return self.attached_objects[i] + except IndexError: + raise ValueError, "trying to access invalid attached object" + + def convert_to(self, obj): + try: + return self.object_to_number[obj] + except KeyError: + num = len(self.attached_objects) + self.object_to_number[obj] = num + self.attached_objects.append(obj) + return num + Address.signed = property(_signed_accessor) Address.unsigned = property(_unsigned_accessor) Address.char = property(_char_accessor) Address.address = property(_address_accessor) - +Address.attached = property(_attached_accessor) NULL = Address() simulator = MemorySimulator() Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 4 10:14:45 2005 @@ -125,3 +125,16 @@ addr.char[10] = "c" assert (addr + 10).char[0] == "c" + def test_attached_pyobjects(self): + def f(x): + return x + 1 + def g(x): + return x - 1 + addr = raw_malloc(100) + addr.attached[0] = f + addr.attached[1] = g + assert addr.attached[0] == f + assert addr.attached[1] == g + assert addr.attached[0](1) == 2 + assert addr.attached[1](0) == -1 + Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Thu Aug 4 10:14:45 2005 @@ -225,16 +225,6 @@ s = malloc(S) py.test.raises(TypeError, "a[0] = s") -def DONOTtest_immortal_parent(): - S1 = GcStruct('substruct', ('x', Signed)) - S = GcStruct('parentstruct', ('s1', S1)) - p = malloc(S, immortal=True) - p1 = p.s1 - p1.x = 5 - del p - p = cast_pointer(Ptr(S), p1) - assert p.s1.x == 5 - def DONOTtest_getRuntimeTypeInfo(): S = GcStruct('s', ('x', Signed)) py.test.raises(ValueError, "getRuntimeTypeInfo(S)") From cfbolz at codespeak.net Thu Aug 4 10:39:23 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 4 Aug 2005 10:39:23 +0200 (CEST) Subject: [pypy-svn] r15595 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050804083923.828E827B69@code1.codespeak.net> Author: cfbolz Date: Thu Aug 4 10:39:22 2005 New Revision: 15595 Modified: pypy/dist/pypy/rpython/memory/lladdress.py pypy/dist/pypy/rpython/memory/simulator.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: add implementation of raw_malloc Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 4 10:39:22 2005 @@ -119,7 +119,7 @@ simulator.free(addr.intaddress) def raw_memcopy(addr1, addr2, size): - pass + simulator.memcopy(addr1.intaddress, addr2.intaddress, size) supported_access_types = {"signed": lltype.Signed, Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Thu Aug 4 10:39:22 2005 @@ -50,6 +50,16 @@ self.status[offset:offset + len(value)] = s assert len(self.memory) == self.size + def memcopy(self, offset1, other, offset2, size): + if offset1 + size > self.size: + raise MemorySimulatorError, "trying to access memory between blocks" + if offset2 + size > other.size: + raise MemorySimulatorError, "trying to access memory between blocks" + print self.memory[offset1:offset1+size] + print self.status[offset1:offset1+size] + other.memory[offset2:offset2+size] = self.memory[offset1:offset1+size] + other.status[offset2:offset2+size] = self.status[offset1:offset1+size] + class MemorySimulator(object): size_of_simulated_ram = 64 * 1024 * 1024 def __init__(self, ram_size = None): @@ -100,5 +110,8 @@ block.setbytes(offset, struct.pack(fmt, *types)) def memcopy(self, address1, address2, size): - data = self.getstruct("c" * size, address1) - self.setstruct("c" * size, address2, *data) + block1 = self.find_block(address1) + block2 = self.find_block(address2) + offset1 = address1 - block1.baseaddress + offset2 = address2 - block2.baseaddress + block1.memcopy(offset1, block2, offset2, size) Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 4 10:39:22 2005 @@ -137,4 +137,16 @@ assert addr.attached[1] == g assert addr.attached[0](1) == 2 assert addr.attached[1](0) == -1 - + + def test_memcopy(self): + def f(x): + return x + 1 + addr = raw_malloc(100) + addr.attached[0] = f + (addr + 10).signed[0] = 42 + (addr + 20).char[0] = "a" + addr1 = raw_malloc(100) + raw_memcopy(addr, addr1, 100) + assert addr1.attached[0](0) == 1 + assert (addr1 + 10).signed[0] == 42 + assert (addr1 + 20).char[0] == "a" From arigo at codespeak.net Thu Aug 4 10:42:28 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 10:42:28 +0200 (CEST) Subject: [pypy-svn] r15596 - pypy/dist/lib-python Message-ID: <20050804084228.AFCEC27B60@code1.codespeak.net> Author: arigo Date: Thu Aug 4 10:42:26 2005 New Revision: 15596 Modified: pypy/dist/lib-python/conftest.py Log: The --file option was renamed to --uselibfile. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Aug 4 10:42:26 2005 @@ -847,7 +847,7 @@ if regrtest.oldstyle: pypy_options.append('--oldstyle') if regrtest.uselibfile: - pypy_options.append('--file') + pypy_options.append('--uselibfile') pypy_options.extend( ['--usemodules=%s' % mod for mod in pypy_option.usemodules]) sopt = " ".join(pypy_options) From cfbolz at codespeak.net Thu Aug 4 10:43:29 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 4 Aug 2005 10:43:29 +0200 (CEST) Subject: [pypy-svn] r15597 - pypy/dist/pypy/rpython/memory Message-ID: <20050804084329.718AE27B60@code1.codespeak.net> Author: cfbolz Date: Thu Aug 4 10:43:27 2005 New Revision: 15597 Modified: pypy/dist/pypy/rpython/memory/simulator.py Log: oops, remove debug prints Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Thu Aug 4 10:43:27 2005 @@ -55,8 +55,6 @@ raise MemorySimulatorError, "trying to access memory between blocks" if offset2 + size > other.size: raise MemorySimulatorError, "trying to access memory between blocks" - print self.memory[offset1:offset1+size] - print self.status[offset1:offset1+size] other.memory[offset2:offset2+size] = self.memory[offset1:offset1+size] other.status[offset2:offset2+size] = self.status[offset1:offset1+size] From arigo at codespeak.net Thu Aug 4 11:27:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 11:27:30 +0200 (CEST) Subject: [pypy-svn] r15598 - pypy/dist/lib-python Message-ID: <20050804092730.B94EF27B6D@code1.codespeak.net> Author: arigo Date: Thu Aug 4 11:27:28 2005 New Revision: 15598 Modified: pypy/dist/lib-python/failure_list.txt Log: Investigated test_new Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 11:27:28 2005 @@ -17,3 +17,7 @@ test_decorator fails because globals and locals are None in a nested function ? + +test_new + fails because our compiler (and also the 'compiler' package) produce + a STORE_NAME instead of a STORE_GLOBAL for the input "global a; a=5" From arigo at codespeak.net Thu Aug 4 11:42:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 11:42:02 +0200 (CEST) Subject: [pypy-svn] r15599 - in pypy/dist/pypy/translator: . c c/src goal Message-ID: <20050804094202.67D1A27B60@code1.codespeak.net> Author: arigo Date: Thu Aug 4 11:41:59 2005 New Revision: 15599 Added: pypy/dist/pypy/translator/goal/app_basic_example.py - copied unchanged from r15587, pypy/dist/pypy/translator/goal/app_example.py pypy/dist/pypy/translator/goal/targetpypystandalone.py - copied, changed from r15588, pypy/dist/pypy/translator/goal/targetpypymain.py Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/goal/app_main.py pypy/dist/pypy/translator/goal/targetpypymain.py pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/translator.py Log: Support for stand-alone translation targets, with a standalone PyPy in targetpypystandalone.py: * added the standalone flag to Translator.ccompile(), for convenience * app_main.entry_point() now takes an explicit argument for sys.executable * app_basic_example.py is the previous version of app_example.py, i.e. the one not dropping in the interactive console (otherwise, we get the interactive console at the beginning of translate_pypy) * always #include "Python.h" for now, for the macros * fix for a bug I'm not sure I understood fully -- avoids "None" PyObject constants. (might be introduced by backend_optimizations.) Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Thu Aug 4 11:41:59 2005 @@ -38,7 +38,7 @@ mix.extend(link.args) if hasattr(link, 'llexitcase'): self.more_ll_values.append(link.llexitcase) - else: + elif link.exitcase is not None: mix.append(Constant(link.exitcase)) traverse(visit, graph) resultvar = graph.getreturnvar() Modified: pypy/dist/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_include.h (original) +++ pypy/dist/pypy/translator/c/src/g_include.h Thu Aug 4 11:41:59 2005 @@ -2,8 +2,12 @@ /************************************************************/ /*** C header file for code produced by genc.py ***/ +/* 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 + */ +#include "Python.h" #ifndef PYPY_STANDALONE -# include "Python.h" # include "compile.h" # include "frameobject.h" # include "structmember.h" Modified: pypy/dist/pypy/translator/goal/app_main.py ============================================================================== --- pypy/dist/pypy/translator/goal/app_main.py (original) +++ pypy/dist/pypy/translator/goal/app_main.py Thu Aug 4 11:41:59 2005 @@ -2,9 +2,9 @@ # XXX very incomplete! Blindly runs the file named as first argument. # No option checking, no interactive console, no fancy hooks. -def entry_point(argv): +def entry_point(executable, argv): import sys - sys.executable = "pypy" + sys.executable = executable sys.argv = argv # with PyPy in top of CPython we can only have around 100 # but we need more in the translated PyPy for the compiler package Modified: pypy/dist/pypy/translator/goal/targetpypymain.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypymain.py Thu Aug 4 11:41:59 2005 @@ -32,8 +32,9 @@ for arg in argv: debug(" argv -> " + arg) try: + w_executable = space.wrap("pypy") w_argv = space.newlist([space.wrap(s) for s in argv]) - w_exitcode = space.call_function(w_entry_point, w_argv) + w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) # try to pull it all in ## from pypy.interpreter import main, interactive, error ## con = interactive.PyPyConsole(space) @@ -67,7 +68,7 @@ w_entry_point = space.getitem(w_dict, space.wrap('entry_point')) # sanity-check: call the entry point - res = entry_point("app_example.py") + res = entry_point("app_basic_example.py") assert res == 0 return entry_point, [SomeString()] Copied: pypy/dist/pypy/translator/goal/targetpypystandalone.py (from r15588, pypy/dist/pypy/translator/goal/targetpypymain.py) ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Thu Aug 4 11:41:59 2005 @@ -22,18 +22,14 @@ # __________ Entry point __________ -def entry_point(argvstring): +def entry_point(argv): debug("entry point starting") - debug(argvstring) - if argvstring: - argv = [argvstring] - else: - argv = [] for arg in argv: debug(" argv -> " + arg) try: - w_argv = space.newlist([space.wrap(s) for s in argv]) - w_exitcode = space.call_function(w_entry_point, w_argv) + w_executable = space.wrap(argv[0]) + w_argv = space.newlist([space.wrap(s) for s in argv[1:]]) + w_exitcode = space.call_function(w_entry_point, w_executable, w_argv) # try to pull it all in ## from pypy.interpreter import main, interactive, error ## con = interactive.PyPyConsole(space) @@ -67,18 +63,8 @@ w_entry_point = space.getitem(w_dict, space.wrap('entry_point')) # sanity-check: call the entry point - res = entry_point("app_example.py") + res = entry_point(["pypy", "app_basic_example.py"]) assert res == 0 - return entry_point, [SomeString()] + return entry_point, None -def get_llinterp_args(): - from pypy.rpython import rstr - ll_str = rstr.string_repr.convert_const("app_example.py") - return [ll_str] - - -# _____ Run translated _____ -def run(c_entry_point): - exitcode = c_entry_point(os.path.join(this_dir, 'app_example.py')) - assert exitcode == 0 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Thu Aug 4 11:41:59 2005 @@ -72,6 +72,7 @@ from pypy.translator.translator import Translator from pypy.translator.ann_override import PyPyAnnotatorPolicy from pypy.annotation import model as annmodel +from pypy.annotation import listdef from pypy.tool.cache import Cache from pypy.annotation.model import SomeObject from pypy.tool.udir import udir @@ -93,7 +94,7 @@ # __________ Main __________ def analyse(target): - global t, entry_point, inputtypes + global t, entry_point, inputtypes, standalone if target: entry_point, inputtypes = target() @@ -103,6 +104,11 @@ # otherwise we have been loaded a = t.annotator t.frozen = False + standalone = inputtypes is None + if standalone: + ldef = listdef.ListDef(None, annmodel.SomeString()) + inputtypes = [annmodel.SomeList(ldef)] + if listen_port: run_async_server() if not options['-no-a']: @@ -590,16 +596,20 @@ print 'Not generating C code.' elif options['-c']: print 'Generating C code without compiling it...' - filename = t.ccompile(really_compile=False) + filename = t.ccompile(really_compile=False, + standalone=standalone) update_usession_dir() print 'Written %s.' % (filename,) else: print 'Generating and compiling C code...' - c_entry_point = t.ccompile() + c_entry_point = t.ccompile(standalone=standalone) update_usession_dir() if not options['-o']: print 'Running!' - targetspec_dic['run'](c_entry_point) + if standalone: + os.system(c_entry_point) + else: + targetspec_dic['run'](c_entry_point) except SystemExit: raise except: Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Thu Aug 4 11:41:59 2005 @@ -252,17 +252,19 @@ mod = make_module_from_pyxstring(name, udir, pyxcode) return getattr(mod, name) - def ccompile(self, really_compile=True): + def ccompile(self, really_compile=True, standalone=False): """Returns compiled function (living in a new C-extension module), compiled using the C generator. """ if self.annotator is not None: self.frozen = True - cbuilder = self.cbuilder(standalone=False) + cbuilder = self.cbuilder(standalone=standalone) c_source_filename = cbuilder.generate_source() if not really_compile: return c_source_filename cbuilder.compile() + if standalone: + return cbuilder.executable_name cbuilder.import_module() return cbuilder.get_entry_point() From arigo at codespeak.net Thu Aug 4 11:51:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 11:51:44 +0200 (CEST) Subject: [pypy-svn] r15601 - pypy/dist/pypy/translator/c/test Message-ID: <20050804095144.F133327B60@code1.codespeak.net> Author: arigo Date: Thu Aug 4 11:51:44 2005 New Revision: 15601 Modified: pypy/dist/pypy/translator/c/test/test_typed.py Log: Added a test for ord() unsignedness. Modified: pypy/dist/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_typed.py (original) +++ pypy/dist/pypy/translator/c/test/test_typed.py Thu Aug 4 11:51:44 2005 @@ -306,6 +306,12 @@ i = r_uint(value) assert f(i) == fn(i) + def test_ord_returns_a_positive(self): + def fn(i=int): + return ord(chr(i)) + f = self.getcompiled(fn) + assert f(255) == 255 + def test_hash_preservation(self): class C: pass From arigo at codespeak.net Thu Aug 4 11:52:40 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 11:52:40 +0200 (CEST) Subject: [pypy-svn] r15602 - pypy/dist/pypy/translator Message-ID: <20050804095240.E745A27B60@code1.codespeak.net> Author: arigo Date: Thu Aug 4 11:52:40 2005 New Revision: 15602 Modified: pypy/dist/pypy/translator/translator.py Log: This function doesn't do anything with its arguments, so better remove them. Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Thu Aug 4 11:52:40 2005 @@ -100,7 +100,7 @@ dest = make_dot(graph.name, graph) os.system('gv %s' % str(dest)) - def view(self, *functions): + def view(self): """Shows the control flow graph with annotations if computed. Requires 'dot' and pygame.""" from pypy.translator.tool.graphpage import FlowGraphPage From nik at codespeak.net Thu Aug 4 12:06:16 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 4 Aug 2005 12:06:16 +0200 (CEST) Subject: [pypy-svn] r15604 - in pypy/dist: lib-python lib-python/modified-2.4.1/test pypy/interpreter pypy/module/__builtin__ pypy/module/__builtin__/test pypy/module/array Message-ID: <20050804100616.8D54B27B60@code1.codespeak.net> Author: nik Date: Thu Aug 4 12:06:12 2005 New Revision: 15604 Added: pypy/dist/lib-python/modified-2.4.1/test/test_array.py - copied, changed from r15538, pypy/dist/lib-python/2.4.1/test/test_array.py pypy/dist/pypy/module/array/ pypy/dist/pypy/module/array/__init__.py (contents, props changed) pypy/dist/pypy/module/array/app_array.py (contents, props changed) Modified: pypy/dist/lib-python/conftest.py pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/module/__builtin__/app_buffer.py pypy/dist/pypy/module/__builtin__/test/test_buffer.py Log: integrated the array module. this one doesn't break the translation. ;) in fact i have also been able to translate successfully with _sre enabled - the problem was the faked array module. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Aug 4 12:06:12 2005 @@ -355,7 +355,7 @@ RegrTest('test_al.py', enabled=False, dumbtest=1), RegrTest('test_anydbm.py', enabled=True, core=True), RegrTest('test_applesingle.py', enabled=False), - RegrTest('test_array.py', enabled=False), + RegrTest('test_array.py', enabled=True), RegrTest('test_asynchat.py', enabled=False), RegrTest('test_atexit.py', enabled=False, dumbtest=1, core=True), RegrTest('test_audioop.py', enabled=False, dumbtest=1), Copied: pypy/dist/lib-python/modified-2.4.1/test/test_array.py (from r15538, pypy/dist/lib-python/2.4.1/test/test_array.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_array.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_array.py Thu Aug 4 12:06:12 2005 @@ -5,7 +5,7 @@ import unittest from test import test_support -from weakref import proxy +#from weakref import proxy import array, cStringIO, math tests = [] # list to accumulate all tests @@ -635,7 +635,8 @@ b = buffer(a) self.assertEqual(b[0], a.tostring()[0]) - def test_weakref(self): + def DONOTtest_weakref(self): + # XXX disabled until PyPy grows weakref support s = array.array(self.typecode, self.example) p = proxy(s) self.assertEqual(p.tostring(), s.tostring()) Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Aug 4 12:06:12 2005 @@ -163,7 +163,8 @@ except AttributeError: pass - modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs'] + modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', + 'array'] if self.options.nofaking: modules.append('posix') Modified: pypy/dist/pypy/module/__builtin__/app_buffer.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_buffer.py (original) +++ pypy/dist/pypy/module/__builtin__/app_buffer.py Thu Aug 4 12:06:12 2005 @@ -1,5 +1,7 @@ +# NOT_RPYTHON (because of array import) # Might probably be deprecated in Python at some point. import sys +from array import array from struct import pack, unpack class buffer(object): @@ -25,8 +27,9 @@ object = str_object elif isinstance(object, buffer): object = object.buf + elif isinstance(object, array): + object = object.tostring() else: - # XXX check for more types raise TypeError, "buffer object expected" if offset < 0: raise ValueError, "offset must be zero or positive" Modified: pypy/dist/pypy/module/__builtin__/test/test_buffer.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_buffer.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_buffer.py Thu Aug 4 12:06:12 2005 @@ -19,3 +19,9 @@ assert b[0:8] == "\x00\x00\x00a\x00\x00\x00b" else: assert b[0:8] == "a\x00\x00\x00b\x00\x00\x00" + + def test_array_buffer(self): + import array + b = buffer(array.array("B", [1, 2, 3])) + assert len(b) == 3 + assert b[0:3] == "\x01\x02\x03" Added: pypy/dist/pypy/module/array/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/array/__init__.py Thu Aug 4 12:06:12 2005 @@ -0,0 +1,11 @@ +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + appleveldefs = { + '__doc__' : 'app_array.__doc__', + '__name__' : 'app_array.__name__', + 'array' : 'app_array.array', + 'ArrayType' : 'app_array.ArrayType', + } + interpleveldefs = { + } Added: pypy/dist/pypy/module/array/app_array.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/array/app_array.py Thu Aug 4 12:06:12 2005 @@ -0,0 +1,480 @@ +# NOT_RPYTHON +"""This module defines an object type which can efficiently represent +an array of basic values: characters, integers, floating point +numbers. Arrays are sequence types and behave very much like lists, +except that the type of objects stored in them is constrained. The +type is specified at object creation time by using a type code, which +is a single character. The following type codes are defined: + + Type code C Type Minimum size in bytes + 'c' character 1 + 'b' signed integer 1 + 'B' unsigned integer 1 + 'u' Unicode character 2 + 'h' signed integer 2 + 'H' unsigned integer 2 + 'i' signed integer 2 + 'I' unsigned integer 2 + 'l' signed integer 4 + 'L' unsigned integer 4 + 'f' floating point 4 + 'd' floating point 8 + +The constructor is: + +array(typecode [, initializer]) -- create a new array +""" +import sys +from struct import pack, unpack + +if sys.maxunicode == 65535: + UNICODE_SIZE = 2 + UNICODE_FORMAT = "H" +else: + UNICODE_SIZE = 4 + UNICODE_FORMAT = "I" + +def c_type_check(x): + if not isinstance(x, str) or len(x) != 1: + raise TypeError("array item must be char") + return x + +def general_int_type_check(x, lower_bound, upper_bound): + if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)): + raise TypeError("an integer is required") + x_int = int(x) + if not (x_int >= lower_bound and x_int <= upper_bound): + raise OverflowError("integer is not in the allowed range") + return x_int + +def b_type_check(x): + return general_int_type_check(x, -128, 127) + +def BB_type_check(x): + return general_int_type_check(x, 0, 255) + +def u_type_check(x): + if isinstance(x, str): + if len(x) / UNICODE_SIZE == 1: + # XXX Problem: CPython will gladly accept any unicode codepoint + # up to 0xFFFFFFFF in UCS-4 builds here, but unichr which is used + # to implement decode for unicode_internal in PyPy will + # reject anything above 0x00110000. I don't think there is a + # way to replicate CPython behaviour without resorting to C. + x_uni = x[:UNICODE_SIZE].decode("unicode_internal") + else: + raise TypeError("array item must be unicode character") + elif isinstance(x, unicode): + x_uni = x + else: + raise TypeError("array item must be unicode character") + if len(x_uni) != 1: + raise TypeError("array item must be unicode character") + return x_uni + +def h_type_check(x): + return general_int_type_check(x, -32768, 32767) + +def HH_type_check(x): + return general_int_type_check(x, 0, 65535) + +def i_type_check(x): + return general_int_type_check(x, -2147483648, 2147483647) + +def general_long_type_check(x, lower_bound, upper_bound): + if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)): + raise TypeError("an integer is required") + x_long = long(x) + if not (x_long >= lower_bound and x_long <= upper_bound): + raise OverflowError("integer/long is not in the allowed range") + return x_long + +def II_type_check(x): + return general_long_type_check(x, 0, 4294967295L) + +l_type_check = i_type_check + +LL_type_check = II_type_check + +def f_type_check(x): + if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)): + raise TypeError("a float is required") + x_float = float(x) + # XXX This is not exactly a nice way of checking bounds. Formerly, I tried + # this: return unpack("f", pack("f", x_float))[0] + # Which works in CPython, but PyPy struct is not currently intelligent + # enough to handle this. + if x_float > 3.4028e38: + x_float = 3.4028e38 + elif x_float < -3.4028e38: + x_float = -3.4028e38 + return x_float + +def d_type_check(x): + if not (isinstance(x, int) or isinstance(x, long) or isinstance(x, float)): + raise TypeError("a float is required") + return float(x) + +def dummy_type_check(x): + return x + +# XXX Assuming fixed sizes of the different types, independent of platform. +# These are the same assumptions that struct makes at the moment. +descriptors = { + 'c' : ('char', 1, c_type_check), + 'b' : ('signed char', 1, b_type_check), + 'B' : ('unsigned char', 1, BB_type_check), + 'u' : ('Py_UNICODE', UNICODE_SIZE, u_type_check), + 'h' : ('signed short', 2, h_type_check), + 'H' : ('unsigned short', 2, HH_type_check), + 'i' : ('signed int', 4, i_type_check), + 'I' : ('unsigned int', 4, II_type_check), + 'l' : ('signed long', 4, l_type_check), + 'L' : ('unsigned long', 4, LL_type_check), + 'f' : ('float', 4, f_type_check), + 'd' : ('double', 8, d_type_check), +} + +class array(object): + """array(typecode [, initializer]) -> array + + Return a new array whose items are restricted by typecode, and + initialized from the optional initializer value, which must be a list, + string. or iterable over elements of the appropriate type. + + Arrays represent basic values and behave very much like lists, except + the type of objects stored in them is constrained. + + Methods: + + append() -- append a new item to the end of the array + buffer_info() -- return information giving the current memory info + byteswap() -- byteswap all the items of the array + count() -- return number of occurences of an object + extend() -- extend array by appending multiple elements from an iterable + fromfile() -- read items from a file object + fromlist() -- append items from the list + fromstring() -- append items from the string + index() -- return index of first occurence of an object + insert() -- insert a new item into the array at a provided position + pop() -- remove and return item (default last) + read() -- DEPRECATED, use fromfile() + remove() -- remove first occurence of an object + reverse() -- reverse the order of the items in the array + tofile() -- write all items to a file object + tolist() -- return the array converted to an ordinary list + tostring() -- return the array converted to a string + write() -- DEPRECATED, use tofile() + + Attributes: + + typecode -- the typecode character used to create the array + itemsize -- the length in bytes of one array item + """ + __slots__ = ["typecode", "itemsize", "_data", "_descriptor", "__weakref__"] + + def __new__(cls, typecode, initializer=[]): + self = object.__new__(cls) + if not isinstance(typecode, str) or len(typecode) != 1: + raise TypeError( + "array() argument 1 must be char, not %s" % type(typecode)) + if not descriptors.has_key(typecode): + raise ValueError( + "bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)") + self._descriptor = descriptors[typecode] + self._data = [] + self.typecode = typecode + self.itemsize = self._descriptor[1] + if isinstance(initializer, list): + self.fromlist(initializer) + elif isinstance(initializer, str): + self.fromstring(initializer) + elif isinstance(initializer, unicode) and self.typecode == "u": + self.fromunicode(initializer) + else: + self.extend(initializer) + return self + + ##### array-specific operations + + def fromfile(self, f, n): + """Read n objects from the file object f and append them to the end of + the array. Also called as read.""" + if not isinstance(f, file): + raise TypeError("arg1 must be open file") + for i in range(n): + item = f.read(self.itemsize) + if len(item) < self.itemsize: + raise EOFError("not enough items in file") + self.fromstring(item) + + def fromlist(self, l): + """Append items to array from list.""" + if not isinstance(l, list): + raise TypeError("arg must be list") + self._fromiterable(l) + + def fromstring(self, s): + """Appends items from the string, interpreting it as an array of machine + values, as if it had been read from a file using the fromfile() + method).""" + if isinstance(s, unicode): + s = str(s) + if not (isinstance(s, str) or isinstance(s, buffer)): + raise TypeError( + "fromstring() argument 1 must be string or read-only buffer") + if len(s) % self.itemsize != 0: + raise ValueError("string length not a multiple of item size") + items = [] + if self.typecode == "u": + for i in range(0, len(s), self.itemsize): + items.append(u_type_check(s[i:i + self.itemsize])) + else: + for i in range(0, len(s), self.itemsize): + item = unpack(self.typecode, s[i:i + self.itemsize])[0] + # the item needn't be type checked if unpack succeeded + items.append(item) + self._data.extend(items) + + def fromunicode(self, ustr): + """Extends this array with data from the unicode string ustr. The array + must be a type 'u' array; otherwise a ValueError is raised. Use + array.fromstring(ustr.encode(...)) to append Unicode data to an array of + some other type.""" + if not self.typecode == "u": + raise ValueError( + "fromunicode() may only be called on type 'u' arrays") + if isinstance(ustr, unicode): + self._fromiterable(ustr) + elif isinstance(ustr, str) or isinstance(ustr, buffer): + # CPython strangely truncates string arguments at multiples of the + # unicode byte size ... + trunc_s = ustr[:len(ustr) - (len(ustr) % self.itemsize)] + self.fromstring(trunc_s) + else: + raise TypeError( + "fromunicode() argument 1 must be string or read-only buffer") + + def tofile(self, f): + """Write all items (as machine values) to the file object f. Also + called as write.""" + if not isinstance(f, file): + raise TypeError("arg must be open file") + f.write(self.tostring()) + + def tolist(self): + """Convert array to an ordinary list with the same items.""" + return self._data[:] + + def tostring(self): + """Convert the array to an array of machine values and return the string + representation.""" + if self.typecode == "u": + return u"".join(self._data).encode("unicode_internal") + else: + strings = [] + for item in self._data: + strings.append(pack(self.typecode, item)) + return "".join(strings) + + def tounicode(self): + """Convert the array to a unicode string. The array must be a type 'u' + array; otherwise a ValueError is raised. Use array.tostring().decode() + to obtain a unicode string from an array of some other type.""" + if self.typecode != "u": + raise ValueError("tounicode() may only be called on type 'u' arrays") + return u"".join(self._data) + + def byteswap(self): + """Byteswap all items of the array. If the items in the array are not + 1, 2, 4, or 8 bytes in size, RuntimeError is raised.""" + if self.itemsize not in [1, 2, 4, 8]: + raise RuntimeError("byteswap not supported for this array") + bytes = self.tostring() + swapped = [] + for offset in range(0, len(self._data) * self.itemsize, self.itemsize): + l = list(bytes[offset:offset + self.itemsize]) + l.reverse() + swapped += l + self._data = [] + self.fromstring("".join(swapped)) + + def buffer_info(self): + """Return a tuple (address, length) giving the current memory address + and the length in items of the buffer used to hold array's contents. The + length should be multiplied by the itemsize attribute to calculate the + buffer length in bytes. In PyPy the return values are not really + meaningful.""" + return (0, len(self._data)) + + read = fromfile + + write = tofile + + ##### general object protocol + + def __repr__(self): + if len(self._data) == 0: + return "array('%s')" % self.typecode + elif self.typecode == "c": + return "array('%s', %s)" % (self.typecode, repr(self.tostring())) + elif self.typecode == "u": + return "array('%s', %s)" % (self.typecode, repr(self.tounicode())) + else: + return "array('%s', %s)" % (self.typecode, repr(self.tolist())) + + def __copy__(self): + a = array(self.typecode) + a._data = self._data[:] + return a + + def __eq__(self, other): + if not isinstance(other, array): + return NotImplemented + return self._data == other._data + + def __ne__(self, other): + if not isinstance(other, array): + return NotImplemented + return self._data != other._data + + def __lt__(self, other): + if not isinstance(other, array): + return NotImplemented + return self._data < other._data + + def __gt__(self, other): + if not isinstance(other, array): + return NotImplemented + return self._data > other._data + + def __le__(self, other): + if not isinstance(other, array): + return NotImplemented + return self._data <= other._data + + def __ge__(self, other): + if not isinstance(other, array): + return NotImplemented + return self._data >= other._data + + ##### list methods + + def append(self, x): + """Append new value x to the end of the array.""" + x_checked = self._type_check(x) + self._data.append(x_checked) + + def count(self, x): + """Return number of occurences of x in the array.""" + return self._data.count(x) + + def extend(self, iterable): + """Append items to the end of the array.""" + if isinstance(iterable, array) \ + and not self.typecode == iterable.typecode: + raise TypeError("can only extend with array of same kind") + self._fromiterable(iterable) + + def index(self, x): + """Return index of first occurence of x in the array.""" + return self._data.index(x) + + def insert(self, i, x): + """Insert a new item x into the array before position i.""" + x_checked = self._type_check(x) + self._data.insert(i, x_checked) + + def pop(self, i=-1): + """Return the i-th element and delete it from the array. i defaults to + -1.""" + return self._data.pop(i) + + def remove(self, x): + """Remove the first occurence of x in the array.""" + self._data.remove(x) + + def reverse(self): + """Reverse the order of the items in the array.""" + self._data.reverse() + + ##### list protocol + + def __len__(self): + return len(self._data) + + def __add__(self, other): + if not isinstance(other, array): + raise TypeError("can only append array to array") + if self.typecode != other.typecode: + raise TypeError("bad argument type for built-in operation") + return array(self.typecode, self._data + other._data) + + def __mul__(self, repeat): + return array(self.typecode, self._data * repeat) + + __rmul__ = __mul__ + + def __getitem__(self, i): + if isinstance(i, slice): + sliced = array(self.typecode) + sliced._data = self._data[i] + return sliced + return self._data[i] + + def __getslice__(self, i, j): + return self.__getitem__(slice(i, j)) + + def __setitem__(self, i, x): + if isinstance(i, slice): + if not isinstance(x, array): + raise TypeError("can only assign array to array slice") + if x.typecode != self.typecode: + raise TypeError("bad argument type for built-in operation") + self._data[i] = x._data + return + if not (isinstance(i, int) or isinstance(i, long)): + raise TypeError("list indices must be integers") + if i >= len(self._data) or i < -len(self._data): + raise IndexError("array assignment index out of range") + x_checked = self._type_check(x) + self._data[i] = x_checked + + def __setslice__(self, i, j, x): + self.__setitem__(slice(i, j), x) + + def __delitem__(self, i): + del self._data[i] + + def __delslice__(self, i, j): + self.__delitem__(slice(i, j)) + + def __contains__(self, item): + return item in self._data + + def __iadd__(self, other): + if not isinstance(other, array): + raise TypeError("can only extend array with array") + self.extend(other) + return self + + def __imul__(self, repeat): + self._data *= repeat + return self + + def __iter__(self): + return iter(self._data) + + ##### internal methods + + def _type_check(self, x): + return self._descriptor[2](x) + + def _fromiterable(self, iterable): + items = [] + for item in iterable: + item_checked = self._type_check(item) + items.append(item_checked) + self._data.extend(items) + +ArrayType = array From arigo at codespeak.net Thu Aug 4 12:20:04 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 12:20:04 +0200 (CEST) Subject: [pypy-svn] r15606 - in pypy/dist/pypy: interpreter/stablecompiler interpreter/test lib/_stablecompiler Message-ID: <20050804102004.DFDF827B86@code1.codespeak.net> Author: arigo Date: Thu Aug 4 12:20:03 2005 New Revision: 15606 Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/symbols.py pypy/dist/pypy/interpreter/test/test_exec.py pypy/dist/pypy/lib/_stablecompiler/consts.py pypy/dist/pypy/lib/_stablecompiler/pycodegen.py pypy/dist/pypy/lib/_stablecompiler/symbols.py Log: Porting mwh's fix for the 'compiler' package to the two copies of our stablecompiler. See new test case. Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/consts.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/consts.py Thu Aug 4 12:20:03 2005 @@ -8,6 +8,7 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 +SC_REALLY_GLOBAL = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Thu Aug 4 12:20:03 2005 @@ -9,7 +9,7 @@ from pypy.interpreter.stablecompiler import ast, parse, walk, syntax from pypy.interpreter.stablecompiler import pyassem, misc, future, symbols from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL + SC_FREE, SC_CELL, SC_REALLY_GLOBAL from pypy.interpreter.stablecompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pypy.interpreter.stablecompiler.pyassem import TupleArg @@ -286,6 +286,8 @@ self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) + elif scope == SC_REALLY_GLOBAL: + self.emit(prefix + '_GLOBAL', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py Thu Aug 4 12:20:03 2005 @@ -2,7 +2,7 @@ from pypy.interpreter.stablecompiler import ast from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL, SC_UNKNOWN + SC_FREE, SC_CELL, SC_UNKNOWN, SC_REALLY_GLOBAL from pypy.interpreter.stablecompiler.misc import mangle import types @@ -90,7 +90,7 @@ The scope of a name could be LOCAL, GLOBAL, FREE, or CELL. """ if self.globals.has_key(name): - return SC_GLOBAL + return SC_REALLY_GLOBAL if self.cells.has_key(name): return SC_CELL if self.defs.has_key(name): @@ -155,7 +155,7 @@ if sc == SC_UNKNOWN or sc == SC_FREE \ or isinstance(self, ClassScope): self.frees[name] = 1 - elif sc == SC_GLOBAL: + elif sc == SC_GLOBAL or sc == SC_REALLY_GLOBAL: child_globals.append(name) elif isinstance(self, FunctionScope) and sc == SC_LOCAL: self.cells[name] = 1 Modified: pypy/dist/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exec.py (original) +++ pypy/dist/pypy/interpreter/test/test_exec.py Thu Aug 4 12:20:03 2005 @@ -74,3 +74,10 @@ def f(): exec 'raise TypeError' in {} raises(TypeError,f) + + def test_global_stmt(self): + g = {} + l = {} + exec "global a; a=5" in g, l + assert l == {} + assert g['a'] == 5 Modified: pypy/dist/pypy/lib/_stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/consts.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/consts.py Thu Aug 4 12:20:03 2005 @@ -8,6 +8,7 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 +SC_REALLY_GLOBAL = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Thu Aug 4 12:20:03 2005 @@ -10,7 +10,7 @@ from transformer import parse from visitor import walk import pyassem, misc, future, symbols -from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL +from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_REALLY_GLOBAL from consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pyassem import TupleArg @@ -287,6 +287,8 @@ self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) + elif scope == SC_REALLY_GLOBAL: + self.emit(prefix + '_GLOBAL', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) Modified: pypy/dist/pypy/lib/_stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/symbols.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/symbols.py Thu Aug 4 12:20:03 2005 @@ -1,7 +1,8 @@ """Module symbol-table generator""" import ast -from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_UNKNOWN +from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, \ + SC_UNKNOWN, SC_REALLY_GLOBAL from misc import mangle import types @@ -89,7 +90,7 @@ The scope of a name could be LOCAL, GLOBAL, FREE, or CELL. """ if self.globals.has_key(name): - return SC_GLOBAL + return SC_REALLY_GLOBAL if self.cells.has_key(name): return SC_CELL if self.defs.has_key(name): @@ -154,7 +155,7 @@ if sc == SC_UNKNOWN or sc == SC_FREE \ or isinstance(self, ClassScope): self.frees[name] = 1 - elif sc == SC_GLOBAL: + elif sc == SC_GLOBAL or sc == SC_REALLY_GLOBAL: child_globals.append(name) elif isinstance(self, FunctionScope) and sc == SC_LOCAL: self.cells[name] = 1 From arigo at codespeak.net Thu Aug 4 12:20:33 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 12:20:33 +0200 (CEST) Subject: [pypy-svn] r15607 - pypy/dist/pypy/module/array Message-ID: <20050804102033.B6AB927B86@code1.codespeak.net> Author: arigo Date: Thu Aug 4 12:20:33 2005 New Revision: 15607 Modified: pypy/dist/pypy/module/array/ (props changed) Log: fixeol From arigo at codespeak.net Thu Aug 4 12:58:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 12:58:23 +0200 (CEST) Subject: [pypy-svn] r15611 - pypy/dist/pypy/translator/c Message-ID: <20050804105823.DB7D627BA6@code1.codespeak.net> Author: arigo Date: Thu Aug 4 12:58:23 2005 New Revision: 15611 Modified: pypy/dist/pypy/translator/c/genc.py Log: Missing include path for compiling stand-alone executables that still have to find Python.h Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Thu Aug 4 12:58:23 2005 @@ -89,8 +89,12 @@ def compile(self): assert self.c_source_filename assert not self._compiled + # XXX for now, we always include Python.h + from distutils import sysconfig + python_inc = sysconfig.get_python_inc() self.executable_name = build_executable([self.c_source_filename], - include_dirs = [autopath.this_dir]) + include_dirs = [autopath.this_dir, + python_inc]) self._compiled = True return self.executable_name From arigo at codespeak.net Thu Aug 4 12:59:22 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 12:59:22 +0200 (CEST) Subject: [pypy-svn] r15612 - in pypy/dist/pypy/translator/c: . src Message-ID: <20050804105922.8137B27BA6@code1.codespeak.net> Author: arigo Date: Thu Aug 4 12:59:21 2005 New Revision: 15612 Modified: pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/c/src/int.h Log: Using "unsigned int" instead of "Py_UCS4" for now. We need a type name in the struct declarations, which occur before the #includes, so we can't just use Py_UCS4. Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Thu Aug 4 12:59:21 2005 @@ -60,7 +60,7 @@ Unsigned: 'unsigned long @', Float: 'double @', Char: 'char @', - UniChar: 'Py_UCS4 @', + UniChar: 'unsigned int @', Bool: 'char @', Void: 'void @', } @@ -70,7 +70,7 @@ Unsigned: '((unsigned) -1)', Float: '-1.0', Char: '((char) -1)', - UniChar: '((Py_UCS4) -1)', + UniChar: '((unsigned) -1)', Bool: '((char) -1)', Void: '/* error */', } Modified: pypy/dist/pypy/translator/c/src/int.h ============================================================================== --- pypy/dist/pypy/translator/c/src/int.h (original) +++ pypy/dist/pypy/translator/c/src/int.h Thu Aug 4 12:59:21 2005 @@ -161,7 +161,7 @@ #define OP_CAST_PTR_TO_INT(x,r,err) r = (long)(x); /* XXX */ #define OP_CAST_UNICHAR_TO_INT(x,r,err) r = (long)((unsigned long)(x)); /*?*/ -#define OP_CAST_INT_TO_UNICHAR(x,r,err) r = (Py_UCS4)(x); +#define OP_CAST_INT_TO_UNICHAR(x,r,err) r = (unsigned int)(x); /* bool operations */ From arigo at codespeak.net Thu Aug 4 13:32:59 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 4 Aug 2005 13:32:59 +0200 (CEST) Subject: [pypy-svn] r15614 - pypy/dist/lib-python Message-ID: <20050804113259.8C80127BB2@code1.codespeak.net> Author: arigo Date: Thu Aug 4 13:32:59 2005 New Revision: 15614 Modified: pypy/dist/lib-python/failure_list.txt Log: I think test_new is fixed Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 13:32:59 2005 @@ -18,6 +18,6 @@ test_decorator fails because globals and locals are None in a nested function ? -test_new +test_new (FIXED? by mwh patch to stablecompiler and _stablecompiler) fails because our compiler (and also the 'compiler' package) produce a STORE_NAME instead of a STORE_GLOBAL for the input "global a; a=5" From ale at codespeak.net Thu Aug 4 14:17:06 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 4 Aug 2005 14:17:06 +0200 (CEST) Subject: [pypy-svn] r15615 - pypy/dist/lib-python Message-ID: <20050804121706.11BA327BAE@code1.codespeak.net> Author: ale Date: Thu Aug 4 14:17:05 2005 New Revision: 15615 Modified: pypy/dist/lib-python/failure_list.txt Log: I will workand adding len to SeqIter and friends Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 14:17:05 2005 @@ -7,7 +7,7 @@ multiple tests fail because from __future__ import division does not work (true division is never enabled) -test_iterlen +test_iterlen (ale will work on this) fails because len is not implemented for SeqIter (and other structures like generators (reversed) ) From bea at codespeak.net Thu Aug 4 15:04:50 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Thu, 4 Aug 2005 15:04:50 +0200 (CEST) Subject: [pypy-svn] r15616 - pypy/extradoc/sprintinfo Message-ID: <20050804130450.498FD27BB1@code1.codespeak.net> Author: bea Date: Thu Aug 4 15:04:49 2005 New Revision: 15616 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: Updated with my plans for participation. Sten and Simone will join and experience the cafees in Heidelberg while Im working.... Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 4 15:04:49 2005 @@ -19,7 +19,7 @@ Holger Krekel 21st-28th Aug private Richard Emslie 22nd-29th Aug private Michael Hudson (?) ? ? -Beatrice Duering ? ? +Beatrice Duering 21st-30th Aug Hotel Ibis Jacob Hallen ? ? Laura Creighton ? ? Ludovic Aubry ? ? From pedronis at codespeak.net Thu Aug 4 15:32:08 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 15:32:08 +0200 (CEST) Subject: [pypy-svn] r15617 - pypy/dist/lib-python Message-ID: <20050804133208.A842527BB2@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 15:32:07 2005 New Revision: 15617 Modified: pypy/dist/lib-python/failure_list.txt Log: analysed test_builtin failures tryed test_new again: still some problems Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 15:32:07 2005 @@ -15,9 +15,15 @@ test_compiler fails because of "maximum recursion depth exceeded" -test_decorator +test_decorator fails because globals and locals are None in a nested function ? -test_new (FIXED? by mwh patch to stablecompiler and _stablecompiler) - fails because our compiler (and also the 'compiler' package) produce - a STORE_NAME instead of a STORE_GLOBAL for the input "global a; a=5" +test_new FIXED? stil problems with insufficient arg checking + +test_builtin + - our compilers need to recognize BOM markers + - eval etc should accept dict subclasses + - hex/oct should output '-' for negative numbers + - unicode("\u0663", 'raw-unicode-escape') does not work properly + - disallow interning of string subclasses + - __future__ import division problems From pedronis at codespeak.net Thu Aug 4 15:55:10 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 15:55:10 +0200 (CEST) Subject: [pypy-svn] r15618 - pypy/dist/pypy/module/__builtin__/test Message-ID: <20050804135510.521E227BB0@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 15:55:08 2005 New Revision: 15618 Modified: pypy/dist/pypy/module/__builtin__/test/test_special.py Log: pick something that will be faked for a while longer Modified: pypy/dist/pypy/module/__builtin__/test/test_special.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_special.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_special.py Thu Aug 4 15:55:08 2005 @@ -6,8 +6,8 @@ assert not _isfake(_isfake) def app_test__isfake_currently_true(): - import array - assert _isfake(array) + import select + assert _isfake(select) def XXXapp_test__isfake_file(): # only if you are not using --file import sys From pedronis at codespeak.net Thu Aug 4 15:58:03 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 15:58:03 +0200 (CEST) Subject: [pypy-svn] r15619 - in pypy/dist/pypy/interpreter: . test Message-ID: <20050804135803.0B84627BB0@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 15:57:59 2005 New Revision: 15619 Modified: pypy/dist/pypy/interpreter/pycode.py pypy/dist/pypy/interpreter/test/test_code.py Log: fix arg checking to pass test_new Modified: pypy/dist/pypy/interpreter/pycode.py ============================================================================== --- pypy/dist/pypy/interpreter/pycode.py (original) +++ pypy/dist/pypy/interpreter/pycode.py Thu Aug 4 15:57:59 2005 @@ -6,6 +6,7 @@ import dis from pypy.interpreter import eval +from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import NoneNotWrapped from pypy.interpreter.baseobjspace import ObjSpace, W_Root from pypy.tool.cache import Cache @@ -242,8 +243,14 @@ w_cellvars=NoneNotWrapped): code = space.allocate_instance(PyCode, w_subtype) PyCode.__init__(code, space) - code.co_argcount = argcount - code.co_nlocals = nlocals + if argcount < 0: + raise OperationError(space.w_ValueError, + space.wrap("code: argcount must not be negative")) + code.co_argcount = argcount + code.co_nlocals = nlocals + if nlocals < 0: + raise OperationError(space.w_ValueError, + space.wrap("code: nlocals must not be negative")) code.co_stacksize = stacksize code.co_flags = flags code.co_code = codestring Modified: pypy/dist/pypy/interpreter/test/test_code.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_code.py (original) +++ pypy/dist/pypy/interpreter/test/test_code.py Thu Aug 4 15:57:59 2005 @@ -91,3 +91,32 @@ d = {} exec co in d assert d['c'] == 3 + def f(x): + y = 1 + ccode = f.func_code + raises(ValueError, new.code, + -ccode.co_argcount, + ccode.co_nlocals, + ccode.co_stacksize, + ccode.co_flags, + ccode.co_code, + ccode.co_consts, + ccode.co_names, + ccode.co_varnames, + ccode.co_filename, + ccode.co_name, + ccode.co_firstlineno, + ccode.co_lnotab) + raises(ValueError, new.code, + ccode.co_argcount, + -ccode.co_nlocals, + ccode.co_stacksize, + ccode.co_flags, + ccode.co_code, + ccode.co_consts, + ccode.co_names, + ccode.co_varnames, + ccode.co_filename, + ccode.co_name, + ccode.co_firstlineno, + ccode.co_lnotab) From pedronis at codespeak.net Thu Aug 4 16:09:21 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 16:09:21 +0200 (CEST) Subject: [pypy-svn] r15621 - pypy/dist/lib-python Message-ID: <20050804140921.DA0D227BB0@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 16:09:20 2005 New Revision: 15621 Modified: pypy/dist/lib-python/failure_list.txt Log: test_new passes now Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 16:09:20 2005 @@ -18,7 +18,6 @@ test_decorator fails because globals and locals are None in a nested function ? -test_new FIXED? stil problems with insufficient arg checking test_builtin - our compilers need to recognize BOM markers @@ -27,3 +26,5 @@ - unicode("\u0663", 'raw-unicode-escape') does not work properly - disallow interning of string subclasses - __future__ import division problems + +test_new FIXED \ No newline at end of file From hpk at codespeak.net Thu Aug 4 16:16:20 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 4 Aug 2005 16:16:20 +0200 (CEST) Subject: [pypy-svn] r15624 - pypy/dist/pypy/tool/pytest Message-ID: <20050804141620.EDACD27BBF@code1.codespeak.net> Author: hpk Date: Thu Aug 4 16:16:20 2005 New Revision: 15624 Modified: pypy/dist/pypy/tool/pytest/result.py Log: - shallow fix to encoding problem with respect to test reports Modified: pypy/dist/pypy/tool/pytest/result.py ============================================================================== --- pypy/dist/pypy/tool/pytest/result.py (original) +++ pypy/dist/pypy/tool/pytest/result.py Thu Aug 4 16:16:20 2005 @@ -104,7 +104,17 @@ assert submsg.get_main_type() == 'text' fn = submsg.get_filename() assert fn - self.addnamedtext(fn, unicode(submsg.get_payload(), 'utf8')) + # XXX we need to deal better with encodings to + # begin with + content = submsg.get_payload() + for candidate in 'utf8', 'latin1': + try: + text = unicode(content, candidate) + except UnicodeDecodeError: + continue + else: + unicode(content, candidate) + self.addnamedtext(fn, text) def ismodifiedtest(self): # XXX we need proper cross-platform paths! @@ -113,7 +123,7 @@ def __repr__(self): return '<%s (%s) %r rev=%s>' %(self.__class__.__name__, self['outcome'], - self.fspath.purebasename, + self.fspath, self['pypy-revision']) def stdinit(result): From pedronis at codespeak.net Thu Aug 4 17:03:29 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 17:03:29 +0200 (CEST) Subject: [pypy-svn] r15625 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050804150329.92C5F27BB1@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 17:03:28 2005 New Revision: 15625 Added: pypy/dist/lib-python/modified-2.4.1/test/test_coercion.py - copied, changed from r15615, pypy/dist/lib-python/2.4.1/test/test_coercion.py Log: we need a modified test_coercion because our exceptions are new style with a different __str__ repr Copied: pypy/dist/lib-python/modified-2.4.1/test/test_coercion.py (from r15615, pypy/dist/lib-python/2.4.1/test/test_coercion.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_coercion.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_coercion.py Thu Aug 4 17:03:28 2005 @@ -96,7 +96,7 @@ x = eval('a %s b' % op) except: error = sys.exc_info()[:2] - print '... %s' % error[0] + print '... %s' % (error[0].__module__+'.'+error[0].__name__) else: print '=', format_result(x) try: @@ -108,7 +108,7 @@ exec('z %s= b' % op) except: error = sys.exc_info()[:2] - print '... %s' % error[0] + print '... %s' % (error[0].__module__+'.'+error[0].__name__) else: print '=>', format_result(z) @@ -121,7 +121,7 @@ x = eval('%s(a, b)' % op) except: error = sys.exc_info()[:2] - print '... %s' % error[0] + print '... %s' % (error[0].__module__+'.'+error[0].__name__) else: print '=', format_result(x) From nik at codespeak.net Thu Aug 4 17:31:12 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 4 Aug 2005 17:31:12 +0200 (CEST) Subject: [pypy-svn] r15631 - in pypy/dist: lib-python pypy/module/_codecs/test Message-ID: <20050804153112.6200027B8B@code1.codespeak.net> Author: nik Date: Thu Aug 4 17:31:11 2005 New Revision: 15631 Modified: pypy/dist/lib-python/failure_list.txt pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: failing raw_unicode_escape codec test (on top of 2.3.5). fixing this now. Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 17:31:11 2005 @@ -24,6 +24,7 @@ - eval etc should accept dict subclasses - hex/oct should output '-' for negative numbers - unicode("\u0663", 'raw-unicode-escape') does not work properly + (nik is working on this) - disallow interning of string subclasses - __future__ import division problems Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Thu Aug 4 17:31:11 2005 @@ -35,3 +35,7 @@ bytes2 = "\x98\x00\x01\x00" assert bytes2.decode("unicode_internal") == u"\U00010098" assert bytes.decode("unicode_internal") == u"a" + + def test_raw_unicode_escape(self): + assert unicode("\u0663", "raw-unicode-escape") == u"\u0663" + assert u"\u0663".decode("raw-unicode-escape") == "\u0663" From nik at codespeak.net Thu Aug 4 17:53:54 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 4 Aug 2005 17:53:54 +0200 (CEST) Subject: [pypy-svn] r15633 - in pypy/dist: lib-python pypy/module/_codecs pypy/module/_codecs/test Message-ID: <20050804155354.35E9C27B71@code1.codespeak.net> Author: nik Date: Thu Aug 4 17:53:52 2005 New Revision: 15633 Modified: pypy/dist/lib-python/failure_list.txt pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: fixed raw_unicode_escape decoding bug Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Thu Aug 4 17:53:52 2005 @@ -23,8 +23,7 @@ - our compilers need to recognize BOM markers - eval etc should accept dict subclasses - hex/oct should output '-' for negative numbers - - unicode("\u0663", 'raw-unicode-escape') does not work properly - (nik is working on this) + - FIXED unicode("\u0663", 'raw-unicode-escape') does not work properly - disallow interning of string subclasses - __future__ import division problems Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Thu Aug 4 17:53:52 2005 @@ -1621,6 +1621,9 @@ pos = i = res[1] p += res[0] i += 1 + else: + p += unichr(x) + pos += count else: if (x > 0x10000): res = unicode_call_errorhandler( Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Thu Aug 4 17:53:52 2005 @@ -38,4 +38,4 @@ def test_raw_unicode_escape(self): assert unicode("\u0663", "raw-unicode-escape") == u"\u0663" - assert u"\u0663".decode("raw-unicode-escape") == "\u0663" + assert u"\u0663".encode("raw-unicode-escape") == "\u0663" From ale at codespeak.net Thu Aug 4 18:40:49 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 4 Aug 2005 18:40:49 +0200 (CEST) Subject: [pypy-svn] r15634 - pypy/dist/pypy/objspace/std/test Message-ID: <20050804164049.1FFA527B76@code1.codespeak.net> Author: ale Date: Thu Aug 4 18:40:48 2005 New Revision: 15634 Modified: pypy/dist/pypy/objspace/std/test/test_iterobject.py Log: Addded some test for len(iter). Commented out test for deque,xrange and reversed, since they do not pass Modified: pypy/dist/pypy/objspace/std/test/test_iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_iterobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_iterobject.py Thu Aug 4 18:40:48 2005 @@ -2,7 +2,6 @@ from pypy.objspace.std.iterobject import W_SeqIterObject from pypy.interpreter.error import OperationError - class TestW_IterObject: def body3(self, w_iter): @@ -59,3 +58,96 @@ raises(TypeError, iter, C()) + +class AppTest_IterObject: + + def check_iter(self,iterable): + it = iter(iterable) + for i in reversed(range(len(it))): + assert len(it) == i+1 + x = it.next() + print x + raises(StopIteration, it.next) + assert len(it) == 0 + + def test_iter_len_tuple(self): + iterable = (1,2,3,4) + it = iter(iterable) + for i in reversed(range(len(it))): + assert len(it) == i+1 + x = it.next() + print x + raises(StopIteration, it.next) + assert len(it) == 0 + + def test_iter_len_dict(self): + iterable = {1:1,2:2,3:3,4:4} + it = iter(iterable) + length = len(it) + for i in reversed(range(length)): + assert len(it) == i+1 + x = it.next() + raises(StopIteration, it.next) + assert len(it) == 0 + + def test_iter_len_list(self): + iterable = [1,2,3,4] + it = iter(iterable) + for i in reversed(range(len(it))): + assert len(it) == i+1 + x = it.next() + print x + raises(StopIteration, it.next) + assert len(it) == 0 + + def test_iter_len_str(self): + iterable = 'Hello World' + it = iter(iterable) + for i in reversed(range(len(it))): + assert len(it) == i+1 + x = it.next() + print x + raises(StopIteration, it.next) + assert len(it) == 0 + + def test_iter_len_set(self): + iterable = set((1,2,3,4)) + it = iter(iterable) + for i in reversed(range(len(it))): + assert len(it) == i+1 + x = it.next() + print x + raises(StopIteration, it.next) + assert len(it) == 0 + +## def test_iter_len_deque(self): +## from collections import deque +## +## iterable = deque((1,2,3,4)) +## it = iter(iterable) +## for i in reversed(range(len(it))): +## assert len(it) == i+1 +## x = it.next() +## print x +## raises(StopIteration, it.next) +## assert len(it) == 0 +## +## def test_iter_len_xrange(self): +## iterable = xrange(8) +## it = iter(iterable) +## for i in reversed(range(len(it))): +## assert len(it) == i+1 +## x = it.next() +## print x +## raises(StopIteration, it.next) +## assert len(it) == 0 +## +## def test_iter_len_reversed(self): +## iterable = reversed((1,2,3,4)) +## it = iter(iterable) +## for i in reversed(range(len(it))): +## assert len(it) == i+1 +## x = it.next() +## print x +## raises(StopIteration, it.next) +## assert len(it) == 0 From cfbolz at codespeak.net Thu Aug 4 18:50:08 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 4 Aug 2005 18:50:08 +0200 (CEST) Subject: [pypy-svn] r15635 - pypy/dist/pypy/rpython/memory Message-ID: <20050804165008.63E3B27B76@code1.codespeak.net> Author: cfbolz Date: Thu Aug 4 18:50:07 2005 New Revision: 15635 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: factored out get_total_size (will need it in more places soon Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Thu Aug 4 18:50:07 2005 @@ -55,6 +55,16 @@ else: assert 0, "not yet implemented" +def get_total_size(TYPE, i=None): + fixedsize = get_fixed_size(TYPE) + varsize = get_variable_size(TYPE) + if i is None: + assert varsize == 0 + return fixedsize + else: + return fixedsize + i * varsize + + def _expose(T, address): """XXX A nice docstring here""" if isinstance(T, (lltype.Struct, lltype.Array)): @@ -75,13 +85,7 @@ self.__dict__['_layout'] = get_layout(TYPE.TO) def _zero_initialize(self, i=None): - fixedsize = get_fixed_size(self._T) - varsize = get_variable_size(self._T) - if i is None: - assert varsize == 0 - size = fixedsize - else: - size = fixedsize + i * varsize + size = get_total_size(self._T, i) self._address._store("c" * size, *(["\x00"] * size)) def _init_size(self, size): @@ -192,8 +196,6 @@ # I'm not sure whether this is the right way to go... return simulatorptr(PTRTYPE, ptr._address) - - # for now use the simulators raw_malloc def malloc(T, n=None, immortal=False): fixedsize = get_fixed_size(T) From ale at codespeak.net Thu Aug 4 18:54:01 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 4 Aug 2005 18:54:01 +0200 (CEST) Subject: [pypy-svn] r15636 - pypy/dist/pypy/objspace/std Message-ID: <20050804165401.AA4F927B7D@code1.codespeak.net> Author: ale Date: Thu Aug 4 18:54:00 2005 New Revision: 15636 Modified: pypy/dist/pypy/objspace/std/dictobject.py pypy/dist/pypy/objspace/std/iterobject.py Log: Addded some support for len(iter). This seems to work for list,tuples,str, dict, set Please review carefully (The W_DictIterObject changes are a bit scary) Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Thu Aug 4 18:54:00 2005 @@ -318,6 +318,7 @@ w_self.w_dictobject = w_dictobject w_self.len = w_dictobject.used w_self.pos = 0 + w_self.datapos = 0 def return_entry(w_self, entry): raise NotImplementedError @@ -348,18 +349,24 @@ raise OperationError(space.w_RuntimeError, space.wrap("dictionary changed size during iteration")) # look for the next entry - i = w_dictiter.pos + i = w_dictiter.datapos data = w_dict.data while i < len(data): entry = data[i] i += 1 if entry.w_value is not None: - w_dictiter.pos = i + w_dictiter.pos += 1 + w_dictiter.datapos = i return w_dictiter.return_entry(entry) # no more entries w_dictiter.w_dictobject = None raise OperationError(space.w_StopIteration, space.w_None) +def len__DictIterObject(space, w_dictiter): + w_dict = w_dictiter.w_dictobject + if w_dict is None: + return space.wrap(0) + return space.wrap(w_dictiter.len - w_dictiter.pos) # ____________________________________________________________ from pypy.objspace.std import dicttype Modified: pypy/dist/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/iterobject.py (original) +++ pypy/dist/pypy/objspace/std/iterobject.py Thu Aug 4 18:54:00 2005 @@ -34,4 +34,10 @@ w_seqiter.index += 1 return w_item +def len__SeqIter(space, w_seqiter): + if w_seqiter.w_seq is None: + return space.wrap(0) + w_len = space.sub(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.index)) + return w_len + register_all(vars()) From cfbolz at codespeak.net Thu Aug 4 18:58:36 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 4 Aug 2005 18:58:36 +0200 (CEST) Subject: [pypy-svn] r15637 - pypy/dist/pypy/rpython Message-ID: <20050804165836.2CC6A27B76@code1.codespeak.net> Author: cfbolz Date: Thu Aug 4 18:58:35 2005 New Revision: 15637 Added: pypy/dist/pypy/rpython/chooselltype.py Modified: pypy/dist/pypy/rpython/llinterp.py Log: First attempt of a minimally intrusive way of using the llinterpreter with my lltype implementation. A lot of tests actually pass the problem is that constants are not properly handled yet. Added: pypy/dist/pypy/rpython/chooselltype.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/chooselltype.py Thu Aug 4 18:58:35 2005 @@ -0,0 +1,24 @@ +# XXX this whole thing is messy. + +# choose the lltype implementation with the following variable: +# 0 is the original pypy/rpython/lltype.py +# 1 is the lltype implementation on top of the memory simulator: +# pypy/rpython/memory/lltypesimulation.py + +use_lltype_number = 0 + +def raising(*args): + raise NotImplemented, "missing function" + +if use_lltype_number == 0: + from pypy.rpython.lltype import _ptr, Ptr, Void, typeOf, malloc, cast_pointer, PyObject, pyobjectptr + from pypy.rpython.lltype import Array, Struct + from pypy.rpython.rmodel import getfunctionptr +elif use_lltype_number == 1: + from pypy.rpython.lltype import Ptr, Void, typeOf, PyObject + from pypy.rpython.lltype import Array, Struct + from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr, cast_pointer, malloc + pyobjectptr = raising + getfunctionptr = raising +else: + raise ValueError, "unknown lltype number" Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Aug 4 18:58:35 2005 @@ -3,9 +3,9 @@ from pypy.objspace.flow.model import Constant, Variable, last_exception from pypy.rpython.rarithmetic import intmask, r_uint, ovfcheck import py -from pypy.rpython.lltype import _ptr, Ptr, Void, typeOf, malloc, cast_pointer, PyObject, pyobjectptr -from pypy.rpython.lltype import Array, Struct -from pypy.rpython.rmodel import getfunctionptr +from pypy.rpython.chooselltype import _ptr, Ptr, Void, typeOf, malloc, cast_pointer, PyObject, pyobjectptr +from pypy.rpython.chooselltype import Array, Struct +from pypy.rpython.chooselltype import getfunctionptr import math log = py.log.Producer('llinterp') From pedronis at codespeak.net Thu Aug 4 19:02:10 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 4 Aug 2005 19:02:10 +0200 (CEST) Subject: [pypy-svn] r15638 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050804170210.EF9FA27B71@code1.codespeak.net> Author: pedronis Date: Thu Aug 4 19:02:09 2005 New Revision: 15638 Added: pypy/dist/lib-python/modified-2.4.1/test/test_descrtut.py - copied, changed from r15615, pypy/dist/lib-python/2.4.1/test/test_descrtut.py Log: these changes are still needed for test_descrtut Copied: pypy/dist/lib-python/modified-2.4.1/test/test_descrtut.py (from r15615, pypy/dist/lib-python/2.4.1/test/test_descrtut.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_descrtut.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_descrtut.py Thu Aug 4 19:02:09 2005 @@ -72,8 +72,8 @@ [1, 2] >>> exec "x = 3; print x" in a 3 - >>> print sorted(a.keys()) - [1, 2, '__builtins__', 'x'] + >>> print sorted([str(key) for key in a.keys()]) + ['1', '2', '__builtins__', 'x'] >>> print a['x'] 3 >>> @@ -174,49 +174,14 @@ Instead, you can get the same information from the list type: - >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted - ['__add__', - '__class__', - '__contains__', - '__delattr__', - '__delitem__', - '__delslice__', - '__doc__', - '__eq__', - '__ge__', - '__getattribute__', - '__getitem__', - '__getslice__', - '__gt__', - '__hash__', - '__iadd__', - '__imul__', - '__init__', - '__iter__', - '__le__', - '__len__', - '__lt__', - '__mul__', - '__ne__', - '__new__', - '__reduce__', - '__reduce_ex__', - '__repr__', - '__reversed__', - '__rmul__', - '__setattr__', - '__setitem__', - '__setslice__', - '__str__', - 'append', - 'count', - 'extend', - 'index', - 'insert', - 'pop', - 'remove', - 'reverse', - 'sort'] + >>> 'append' in dir(list) # like list.__dict__.keys(), but sorted + True + >>> 'sort' in dir(list) + True + >>> 'pop' in dir(list) + True + >>> '__getitem__' in dir(list) + True The new introspection API gives more information than the old one: in addition to the regular methods, it also shows the methods that are From hpk at codespeak.net Thu Aug 4 20:29:47 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 4 Aug 2005 20:29:47 +0200 (CEST) Subject: [pypy-svn] r15642 - pypy/extradoc/minute Message-ID: <20050804182947.E95EA27B76@code1.codespeak.net> Author: hpk Date: Thu Aug 4 20:29:45 2005 New Revision: 15642 Added: pypy/extradoc/minute/pypy-sync-08-04-2005.txt Log: added the minutes for today's pypy-sync meeting Added: pypy/extradoc/minute/pypy-sync-08-04-2005.txt ============================================================================== --- (empty file) +++ pypy/extradoc/minute/pypy-sync-08-04-2005.txt Thu Aug 4 20:29:45 2005 @@ -0,0 +1,269 @@ +============================================= +pypy-sync developer meeting 4th August 2005 +============================================= + +Attendees:: + Samuele Pedroni, + Adrien Di Mascio, + Carl Friedrich Bolz, + Armin Rigo, + Samuele Pedroni, + Anders Lehmann, + Niklaus Heidimann, + Eric van Riet Paap, + Holger Krekel (minutes/moderation) + +with pre info:: + Richard Emslie, Ludovic Aubry, + +Regular Topics +==================== + +- roll call. holger opens the meeting. + +- activity reports (3 prepared lines of info). + All Attendees submitted activity reports (see `IRC-Log`_ + at the end and 'LAST/NEXT/BLOCKERS' entries in particular) + +- resolve conflicts/blockers + No direct conflicts were discovered. Compliancy work was + discussed under its own topic. + +Topics of the week +=================== + +"regular" more closed sprints? +--------------------------------- + +In a private conversation Bea asked Holger how the developer group +thinks of the hildesheim2-sprint type (which was similar +to the Pre-EP sprint in Gotenburg). A question is: +do we think we want to regularly do sprints where we +only invite developers who are at least half up to +speed with PyPy? Should sprints around conferences always +be completely open and some of the sprints in between +then possibly more closed? + +The group agrees that the actual issue is not so much about +being "closed" per se but about the active developers being +able to pair among themselves. Also it is agreed that interested +developers, especially ones close to the sprint venue, should not +be excluded even from restricted sprints. Around conferences +we always want to invite and prepare for developers completely +new to PyPy, whereas between we'd sometime like to +restrict the sprints to active developers. It is also +clear that we don't want to go against the open source +spirit of allowing interested people to participate. + +0.6.2 release: dropping the idea and just going for 0.7 ... +---------------------------------------------------------------------------- + +It has basically been decided by the hildesheim2 sprint group +that Heidelberg should tackle a 0.7 self-contained PyPy version. +It seems that we then probably want to drop the idea of a +0.6.2 release. But the release goal for 0.6.2, namely +the compliancy goal of again reaching 90% compliancy +for our 2.4.1 based tree, should then be shifted to 0.7. + +The attendants quickly agreed that we drop the 0.6.2 release +and go for 0.7 directly, including the 0.6.2 release goals. + +fixing compliancy bugs +------------------------------------ + +It has been decided by the hildesheim2 sprint group +that we want to have a text file in lib-python +that lists the problems with failing test modules +so that we can share analysis. + +After a short discussion we reach agreement on + +a) we add progress information regarding single compliancy + tests to lib-python/failure_list.txt. If anyone works + longer on a compliancy test then it should be noted + in the file to avoid duplication of work. + +b) fixing a compliancy test should usually be accompanied + by adding a small test in our pypy/ hierarchy. Only + if the test is too obscure to be reproduced nicely + it is ok to not add such a test. + +c) we may need to prepare a bit that we count the failing/suceeding + compliancy tests more correctly. This can probably still + be done at the heidelberg sprint if neccessary. + +Closing +------------------ + +Holger closes the meeting in time at 13:30pm. + +.. _`IRC-log`: + +Here is the full IRC log:: + +Aug 04 12:54:29 --> You are now talking on #pypy-sync +Aug 04 12:58:42 should we start? (we're 6 minutes behind already) +Aug 04 12:58:53 ups, my clock says 12:58 +Aug 04 12:59:00 sorry +Aug 04 12:59:04 then sure, let's start right ahead +Aug 04 12:59:06 and hi +Aug 04 12:59:09 hi! +Aug 04 12:59:11 hi +Aug 04 12:59:16 hi :-) +Aug 04 12:59:16 hi +Aug 04 12:59:17 Hi +Aug 04 12:59:20 hi as well +Aug 04 12:59:36 ok, let's go, here is the agenda: +Aug 04 12:59:44 - roll call. +Aug 04 12:59:44 - activity reports (3 prepared lines of info). +Aug 04 12:59:44 - resolve conflicts/blockers +Aug 04 12:59:44 * Topics of the week * +Aug 04 12:59:44 - regularly more closed sprints? +Aug 04 12:59:44 - 0.6.2 release: dropping the idea and just going for 0.7?! +Aug 04 12:59:44 - fixing compliancy bugs +Aug 04 12:59:44 - (re)assignments +Aug 04 13:00:04 (i will be pretending, my clock is right, so it's exactly 13:00 now :-) +Aug 04 13:00:11 activity reports, i supposed the following order: +Aug 04 13:00:11 :-) +Aug 04 13:00:22 rxe,hpk,ericvrp2,nik,adim,arigo,aleale,cfbolz,pedronis,adim +Aug 04 13:00:28 --- You are now known as rxe +Aug 04 13:00:36 LAST: llvm work with Eric (pbc, operations, bpnn, richards, readability of source +Aug 04 13:00:36 NEXT: would be nice to translate pypy itself - not too far off - but will probably be busy wit +Aug 04 13:00:36 h other stuff +Aug 04 13:00:36 BLOCKERS: none +Aug 04 13:00:41 --- You are now known as hpk +Aug 04 13:00:50 LAST: exception handling in llvm backend +Aug 04 13:00:51 NEXT: operator exceptions (divzero,etc) +Aug 04 13:00:51 BLOCKERS: a lot of XXX in llvm backend, might need to refactor first +Aug 04 13:00:55 LAST: hildesheim2-sprint + after-work/reporting, small fixes + cleanup here and there +Aug 04 13:00:55 NEXT: codespeak-migration, (maybe) improve test-report/translation tools +Aug 04 13:00:55 BLOCKERS: time pressure regarding migration +Aug 04 13:01:02 LAST: integrating _sre and array +Aug 04 13:01:10 NEXT: app-level optimizations for _sre, some array improvements. after that (= next week) i'm probably be free for work on general compliance. +Aug 04 13:01:14 BLOCKERS: - +Aug 04 13:01:27 LAST: gave a course +Aug 04 13:01:27 NEXT: continue astbuilder (only since today) +Aug 04 13:01:27 BLOCKERS: no really blockers, byt small problems for some isntructions +Aug 04 13:01:32 --- adim is now known as luda1 +Aug 04 13:01:39 LAST: vacation +Aug 04 13:01:39 NEXT: vacation +Aug 04 13:01:39 BLOCKERS: none +Aug 04 13:01:45 --- luda1 is now known as adim +Aug 04 13:01:52 LAST: fixing bugs in translate_pypy; getting a stand-alone executable instead of an ext module +Aug 04 13:01:52 NEXT: clean-ups (e.g. the Translator class); work on compliance tests; more bugs shown by translate_pypy +Aug 04 13:01:52 BLOCKERS: - +Aug 04 13:01:56 prev: Compliance tests, getting settled in at DFKI +Aug 04 13:01:58 next: Compliance tests +Aug 04 13:01:59 blockers: none +Aug 04 13:02:07 LAST: Hildesheim sprint, lltypesimulation on top of memory simulator, looking ways to integrate lltypesimulation with llinterp +Aug 04 13:02:07 NEXT: integrating lltypesimulation into lltinterp, enhancing llinterp to be able to use simulated GC (finding roots) +Aug 04 13:02:07 BLOCKERS: none +Aug 04 13:02:30 Last: sprint, fix obscure(tm) intermittent annotator problem, fix what prevented "import code" to succeed +Aug 04 13:02:32 Next: work on open issues +Aug 04 13:02:33 Issues: when we try very clever approaches we should try to think of and add sanity checks +Aug 04 13:03:00 ok, that's activity reports, there are no immediate blockers ... +Aug 04 13:03:15 however, we should talk a bit about how to approach compliancy under its own topic +Aug 04 13:03:46 so on to: regularly doing more closed sprints? +Aug 04 13:03:56 Bea mailed me and there were discussions here and there +Aug 04 13:04:06 what do people think about having two types of sprints +Aug 04 13:04:22 like one completely open and more "closed"? +Aug 04 13:04:49 how closed would "closed" be? +Aug 04 13:05:03 I think I only have tried the "closed" one +Aug 04 13:05:29 cfbolz: i'd suggest to define closed as "enough room for the active developers to pair with each other" +Aug 04 13:05:56 because i think that is really the issue, the more newbies or not-up-to-speed people the less the active developers can pair with each other +Aug 04 13:06:01 sounds good :-) +Aug 04 13:06:08 yes +Aug 04 13:06:28 hildesheim was very productive +Aug 04 13:07:04 any other agreeing/disagreeing opinions on this? +Aug 04 13:07:48 Keeping sprints open around conferences seems a good idea, but having more "closed" ones around "deadlines" should be possible too +Aug 04 13:07:56 I think that it goes somewhat against the opensource idea +Aug 04 13:08:19 not really. depends on definition of "active developers" +Aug 04 13:08:21 I would suggest at least 1-2 days for people that might live nearby and want to get the feeling +Aug 04 13:08:33 ericvrp2: i see your point +Aug 04 13:09:03 for example, i am not worried about heidelberg, because there are quite a lot of people registered that know PyPy reasonably well +Aug 04 13:09:28 so if we had 2-4 newbies showing up, that should be quite ok +Aug 04 13:09:54 so by your definition it would even be a closed sprint :-) +Aug 04 13:10:04 cfbolz: psst! :-) +Aug 04 13:11:07 no, I agree. Open would mean something like after EP where really lots of people showed up rather spontaneously +Aug 04 13:11:08 ok, i would like to summarize that the general opinion is that closed sprints are ok, but we want to be careful to a) not do them to often b) not harshly exclude interested developers c) look that we don't go against the open-source spirit +Aug 04 13:11:19 makes sense to always allow nearby people to show up. We should only recommend to other people to fly to an "open" sprint if they have to fly anyway +Aug 04 13:11:37 seems good +Aug 04 13:12:01 fine! +Aug 04 13:12:11 ok for me. +Aug 04 13:12:46 nik: does it also make sense to you? +Aug 04 13:13:08 yep, fine with me +Aug 04 13:13:32 pedronis, aleale: i presume you don't object either (until you do) +Aug 04 13:13:50 correct +Aug 04 13:14:06 * hpk 's clock is 13:14 now +Aug 04 13:14:20 next topic: 0.6.2 release: dropping the idea and just going for 0.7 ... +Aug 04 13:14:27 it's probably uncontroversial +Aug 04 13:14:37 but i want to follow up on earlier discussions/decisions +Aug 04 13:14:54 i guess that we don't go for any 0.6 release anymore and directly tackle 0.7 at heidelberg +Aug 04 13:15:07 everybody fine with this? +Aug 04 13:15:11 yes +Aug 04 13:15:16 what would have been the focus of 0.6.2? +Aug 04 13:15:29 switch to CPython 2.4.1 +Aug 04 13:15:42 i see +Aug 04 13:15:44 nik: compliance, move to 2.4.1 and the parser running on top of cpython both 2.4 and 2.3 +Aug 04 13:16:09 those goals would be shifted to 0.7 +Aug 04 13:16:32 agreed +Aug 04 13:16:38 yes +Aug 04 13:16:50 ok +Aug 04 13:16:54 ok with this +Aug 04 13:17:00 I'm fine with that +Aug 04 13:17:08 great, then the next topic (we still have 13 minutes according to my clock) +Aug 04 13:17:18 Plans for fixing compliancy bugs +Aug 04 13:17:49 there now is a first incomplete text file failure_list.txt in lib-p?ython +Aug 04 13:18:25 the question is a bit a) how we distribute the tasks/analysis +Aug 04 13:18:43 b) how we tackle fixing compliancy issues (adding tests or not?) +Aug 04 13:19:06 c) do we urgently need to count differently then by failing test file? +Aug 04 13:19:22 a) I propose that whoever starts seriously looking at a test, says so in the failure_list.txt +Aug 04 13:19:52 and then he follows up there too when he found the problem, and finally says if/when the problem is fixed or if he can't fix it +Aug 04 13:20:38 b) let's add tests to our own suite unless they are really too obscure +Aug 04 13:20:57 c) I personally don't care too much about counting tests differently +Aug 04 13:21:13 arigo: but the EU might :-) +Aug 04 13:22:01 the revision xxx before the 2.4.1 switch passed 90% of tests +Aug 04 13:22:01 cfbolz: but counting a whole test file just containing one failure as a complete failure is certainly "good for the EU" :-) +Aug 04 13:22:13 do they mandate a figure, like 95% compliancy? +Aug 04 13:22:20 nik: we promised 90% compliancy +Aug 04 13:22:23 hpk: of course :-) +Aug 04 13:23:03 arigo: i agree to a) and b) but regarding c): i think we should prepare for counting differently before heidelberg - just in case +Aug 04 13:23:14 Lets wait until Heidelberg and see if it is needed +Aug 04 13:23:55 hpk: ok +Aug 04 13:24:00 yes, but armin's point is valid as well: no matter how we count, it's annoying that a lot of tests fail now that passed once +Aug 04 13:24:15 cfbolz: i am not even sure about that: 2.4.1 has maybe just added tests? +Aug 04 13:24:36 maybe +Aug 04 13:24:40 that may be true +Aug 04 13:24:44 i noticed several times +Aug 04 13:24:49 that stuff isn't tested in CPython +Aug 04 13:24:49 counting differently sound alot like early optimization to me +Aug 04 13:25:26 ericvrp2: well, we are really counting wrong currently +Aug 04 13:26:02 ericvrp2: consider one test file with 10000 tests all failing, and one test file with 1 test passing -> compkliancy 50% +Aug 04 13:26:52 although most of the time it's really the other way round right now +Aug 04 13:26:54 hpk: I agree with you, but changing that now (unless 5 minutes work) doesn't sound very productive +Aug 04 13:26:59 hpk: fixing the counting should be easy to do at Heidelberg if needed +Aug 04 13:27:21 hpk: I think that time is better spent trying to fix the tests themselves, for now +Aug 04 13:27:51 ok, fine by me (but i still want to to look _a bit_ into the test reporting, anyway, so i might give that a look as well) +Aug 04 13:28:07 sure +Aug 04 13:28:28 there are at least curerntly encoding-problems which prevent test reports +Aug 04 13:28:35 one suggestion: it would help if the whole compliancy suite was run daily on some server +Aug 04 13:28:40 and the results checked in +Aug 04 13:28:54 nik: yes, i had that on codespeak.net but stopped it when the server was getting unstable +Aug 04 13:29:08 ok, i think we have a conclusion on this +Aug 04 13:29:10 hpk: I can do that here, if you give me your script +Aug 04 13:29:20 cfbolz: ok, will tell you off-this-meeting +Aug 04 13:29:27 ok +Aug 04 13:29:36 * hpk is about to close the meeting +Aug 04 13:30:02 thanks all for coming, and see you on the neighbour channel :-) +Aug 04 13:30:05 :-) +Aug 04 13:30:08 bye +Aug 04 13:30:17 bye +Aug 04 13:30:28 Bye +Aug 04 13:30:36 bye +Aug 04 13:30:40 byebye +Aug 04 13:30:47 bye +Aug 04 13:31:06 <-- arigo (~arigo at arigo.sustaining.supporter.pdpc) has left #pypy-sync +Aug 04 13:31:14 <-- cfbolz (~test at zenon.physi.uni-heidelberg.de) has left #pypy-sync ("Leaving") +Aug 04 13:31:36 <-- nik (~chatzilla at 253.71.77.83.cust.bluewin.ch) has left #pypy-sync +Aug 04 13:31:45 <-- aleale (~chatzilla at clogs.dfki.uni-sb.de) has left #pypy-sync +Aug 04 13:32:16 <-- adim (~adim at logilab.net2.nerim.net) has left #pypy-sync From hpk at codespeak.net Thu Aug 4 20:31:20 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 4 Aug 2005 20:31:20 +0200 (CEST) Subject: [pypy-svn] r15643 - pypy/extradoc/minute Message-ID: <20050804183120.40E8F27B71@code1.codespeak.net> Author: hpk Date: Thu Aug 4 20:31:17 2005 New Revision: 15643 Modified: pypy/extradoc/minute/pypy-sync-08-04-2005.txt Log: ReST fixes Modified: pypy/extradoc/minute/pypy-sync-08-04-2005.txt ============================================================================== --- pypy/extradoc/minute/pypy-sync-08-04-2005.txt (original) +++ pypy/extradoc/minute/pypy-sync-08-04-2005.txt Thu Aug 4 20:31:17 2005 @@ -101,169 +101,169 @@ Here is the full IRC log:: -Aug 04 12:54:29 --> You are now talking on #pypy-sync -Aug 04 12:58:42 should we start? (we're 6 minutes behind already) -Aug 04 12:58:53 ups, my clock says 12:58 -Aug 04 12:59:00 sorry -Aug 04 12:59:04 then sure, let's start right ahead -Aug 04 12:59:06 and hi -Aug 04 12:59:09 hi! -Aug 04 12:59:11 hi -Aug 04 12:59:16 hi :-) -Aug 04 12:59:16 hi -Aug 04 12:59:17 Hi -Aug 04 12:59:20 hi as well -Aug 04 12:59:36 ok, let's go, here is the agenda: -Aug 04 12:59:44 - roll call. -Aug 04 12:59:44 - activity reports (3 prepared lines of info). -Aug 04 12:59:44 - resolve conflicts/blockers -Aug 04 12:59:44 * Topics of the week * -Aug 04 12:59:44 - regularly more closed sprints? -Aug 04 12:59:44 - 0.6.2 release: dropping the idea and just going for 0.7?! -Aug 04 12:59:44 - fixing compliancy bugs -Aug 04 12:59:44 - (re)assignments -Aug 04 13:00:04 (i will be pretending, my clock is right, so it's exactly 13:00 now :-) -Aug 04 13:00:11 activity reports, i supposed the following order: -Aug 04 13:00:11 :-) -Aug 04 13:00:22 rxe,hpk,ericvrp2,nik,adim,arigo,aleale,cfbolz,pedronis,adim -Aug 04 13:00:28 --- You are now known as rxe -Aug 04 13:00:36 LAST: llvm work with Eric (pbc, operations, bpnn, richards, readability of source -Aug 04 13:00:36 NEXT: would be nice to translate pypy itself - not too far off - but will probably be busy wit -Aug 04 13:00:36 h other stuff -Aug 04 13:00:36 BLOCKERS: none -Aug 04 13:00:41 --- You are now known as hpk -Aug 04 13:00:50 LAST: exception handling in llvm backend -Aug 04 13:00:51 NEXT: operator exceptions (divzero,etc) -Aug 04 13:00:51 BLOCKERS: a lot of XXX in llvm backend, might need to refactor first -Aug 04 13:00:55 LAST: hildesheim2-sprint + after-work/reporting, small fixes + cleanup here and there -Aug 04 13:00:55 NEXT: codespeak-migration, (maybe) improve test-report/translation tools -Aug 04 13:00:55 BLOCKERS: time pressure regarding migration -Aug 04 13:01:02 LAST: integrating _sre and array -Aug 04 13:01:10 NEXT: app-level optimizations for _sre, some array improvements. after that (= next week) i'm probably be free for work on general compliance. -Aug 04 13:01:14 BLOCKERS: - -Aug 04 13:01:27 LAST: gave a course -Aug 04 13:01:27 NEXT: continue astbuilder (only since today) -Aug 04 13:01:27 BLOCKERS: no really blockers, byt small problems for some isntructions -Aug 04 13:01:32 --- adim is now known as luda1 -Aug 04 13:01:39 LAST: vacation -Aug 04 13:01:39 NEXT: vacation -Aug 04 13:01:39 BLOCKERS: none -Aug 04 13:01:45 --- luda1 is now known as adim -Aug 04 13:01:52 LAST: fixing bugs in translate_pypy; getting a stand-alone executable instead of an ext module -Aug 04 13:01:52 NEXT: clean-ups (e.g. the Translator class); work on compliance tests; more bugs shown by translate_pypy -Aug 04 13:01:52 BLOCKERS: - -Aug 04 13:01:56 prev: Compliance tests, getting settled in at DFKI -Aug 04 13:01:58 next: Compliance tests -Aug 04 13:01:59 blockers: none -Aug 04 13:02:07 LAST: Hildesheim sprint, lltypesimulation on top of memory simulator, looking ways to integrate lltypesimulation with llinterp -Aug 04 13:02:07 NEXT: integrating lltypesimulation into lltinterp, enhancing llinterp to be able to use simulated GC (finding roots) -Aug 04 13:02:07 BLOCKERS: none -Aug 04 13:02:30 Last: sprint, fix obscure(tm) intermittent annotator problem, fix what prevented "import code" to succeed -Aug 04 13:02:32 Next: work on open issues -Aug 04 13:02:33 Issues: when we try very clever approaches we should try to think of and add sanity checks -Aug 04 13:03:00 ok, that's activity reports, there are no immediate blockers ... -Aug 04 13:03:15 however, we should talk a bit about how to approach compliancy under its own topic -Aug 04 13:03:46 so on to: regularly doing more closed sprints? -Aug 04 13:03:56 Bea mailed me and there were discussions here and there -Aug 04 13:04:06 what do people think about having two types of sprints -Aug 04 13:04:22 like one completely open and more "closed"? -Aug 04 13:04:49 how closed would "closed" be? -Aug 04 13:05:03 I think I only have tried the "closed" one -Aug 04 13:05:29 cfbolz: i'd suggest to define closed as "enough room for the active developers to pair with each other" -Aug 04 13:05:56 because i think that is really the issue, the more newbies or not-up-to-speed people the less the active developers can pair with each other -Aug 04 13:06:01 sounds good :-) -Aug 04 13:06:08 yes -Aug 04 13:06:28 hildesheim was very productive -Aug 04 13:07:04 any other agreeing/disagreeing opinions on this? -Aug 04 13:07:48 Keeping sprints open around conferences seems a good idea, but having more "closed" ones around "deadlines" should be possible too -Aug 04 13:07:56 I think that it goes somewhat against the opensource idea -Aug 04 13:08:19 not really. depends on definition of "active developers" -Aug 04 13:08:21 I would suggest at least 1-2 days for people that might live nearby and want to get the feeling -Aug 04 13:08:33 ericvrp2: i see your point -Aug 04 13:09:03 for example, i am not worried about heidelberg, because there are quite a lot of people registered that know PyPy reasonably well -Aug 04 13:09:28 so if we had 2-4 newbies showing up, that should be quite ok -Aug 04 13:09:54 so by your definition it would even be a closed sprint :-) -Aug 04 13:10:04 cfbolz: psst! :-) -Aug 04 13:11:07 no, I agree. Open would mean something like after EP where really lots of people showed up rather spontaneously -Aug 04 13:11:08 ok, i would like to summarize that the general opinion is that closed sprints are ok, but we want to be careful to a) not do them to often b) not harshly exclude interested developers c) look that we don't go against the open-source spirit -Aug 04 13:11:19 makes sense to always allow nearby people to show up. We should only recommend to other people to fly to an "open" sprint if they have to fly anyway -Aug 04 13:11:37 seems good -Aug 04 13:12:01 fine! -Aug 04 13:12:11 ok for me. -Aug 04 13:12:46 nik: does it also make sense to you? -Aug 04 13:13:08 yep, fine with me -Aug 04 13:13:32 pedronis, aleale: i presume you don't object either (until you do) -Aug 04 13:13:50 correct -Aug 04 13:14:06 * hpk 's clock is 13:14 now -Aug 04 13:14:20 next topic: 0.6.2 release: dropping the idea and just going for 0.7 ... -Aug 04 13:14:27 it's probably uncontroversial -Aug 04 13:14:37 but i want to follow up on earlier discussions/decisions -Aug 04 13:14:54 i guess that we don't go for any 0.6 release anymore and directly tackle 0.7 at heidelberg -Aug 04 13:15:07 everybody fine with this? -Aug 04 13:15:11 yes -Aug 04 13:15:16 what would have been the focus of 0.6.2? -Aug 04 13:15:29 switch to CPython 2.4.1 -Aug 04 13:15:42 i see -Aug 04 13:15:44 nik: compliance, move to 2.4.1 and the parser running on top of cpython both 2.4 and 2.3 -Aug 04 13:16:09 those goals would be shifted to 0.7 -Aug 04 13:16:32 agreed -Aug 04 13:16:38 yes -Aug 04 13:16:50 ok -Aug 04 13:16:54 ok with this -Aug 04 13:17:00 I'm fine with that -Aug 04 13:17:08 great, then the next topic (we still have 13 minutes according to my clock) -Aug 04 13:17:18 Plans for fixing compliancy bugs -Aug 04 13:17:49 there now is a first incomplete text file failure_list.txt in lib-p?ython -Aug 04 13:18:25 the question is a bit a) how we distribute the tasks/analysis -Aug 04 13:18:43 b) how we tackle fixing compliancy issues (adding tests or not?) -Aug 04 13:19:06 c) do we urgently need to count differently then by failing test file? -Aug 04 13:19:22 a) I propose that whoever starts seriously looking at a test, says so in the failure_list.txt -Aug 04 13:19:52 and then he follows up there too when he found the problem, and finally says if/when the problem is fixed or if he can't fix it -Aug 04 13:20:38 b) let's add tests to our own suite unless they are really too obscure -Aug 04 13:20:57 c) I personally don't care too much about counting tests differently -Aug 04 13:21:13 arigo: but the EU might :-) -Aug 04 13:22:01 the revision xxx before the 2.4.1 switch passed 90% of tests -Aug 04 13:22:01 cfbolz: but counting a whole test file just containing one failure as a complete failure is certainly "good for the EU" :-) -Aug 04 13:22:13 do they mandate a figure, like 95% compliancy? -Aug 04 13:22:20 nik: we promised 90% compliancy -Aug 04 13:22:23 hpk: of course :-) -Aug 04 13:23:03 arigo: i agree to a) and b) but regarding c): i think we should prepare for counting differently before heidelberg - just in case -Aug 04 13:23:14 Lets wait until Heidelberg and see if it is needed -Aug 04 13:23:55 hpk: ok -Aug 04 13:24:00 yes, but armin's point is valid as well: no matter how we count, it's annoying that a lot of tests fail now that passed once -Aug 04 13:24:15 cfbolz: i am not even sure about that: 2.4.1 has maybe just added tests? -Aug 04 13:24:36 maybe -Aug 04 13:24:40 that may be true -Aug 04 13:24:44 i noticed several times -Aug 04 13:24:49 that stuff isn't tested in CPython -Aug 04 13:24:49 counting differently sound alot like early optimization to me -Aug 04 13:25:26 ericvrp2: well, we are really counting wrong currently -Aug 04 13:26:02 ericvrp2: consider one test file with 10000 tests all failing, and one test file with 1 test passing -> compkliancy 50% -Aug 04 13:26:52 although most of the time it's really the other way round right now -Aug 04 13:26:54 hpk: I agree with you, but changing that now (unless 5 minutes work) doesn't sound very productive -Aug 04 13:26:59 hpk: fixing the counting should be easy to do at Heidelberg if needed -Aug 04 13:27:21 hpk: I think that time is better spent trying to fix the tests themselves, for now -Aug 04 13:27:51 ok, fine by me (but i still want to to look _a bit_ into the test reporting, anyway, so i might give that a look as well) -Aug 04 13:28:07 sure -Aug 04 13:28:28 there are at least curerntly encoding-problems which prevent test reports -Aug 04 13:28:35 one suggestion: it would help if the whole compliancy suite was run daily on some server -Aug 04 13:28:40 and the results checked in -Aug 04 13:28:54 nik: yes, i had that on codespeak.net but stopped it when the server was getting unstable -Aug 04 13:29:08 ok, i think we have a conclusion on this -Aug 04 13:29:10 hpk: I can do that here, if you give me your script -Aug 04 13:29:20 cfbolz: ok, will tell you off-this-meeting -Aug 04 13:29:27 ok -Aug 04 13:29:36 * hpk is about to close the meeting -Aug 04 13:30:02 thanks all for coming, and see you on the neighbour channel :-) -Aug 04 13:30:05 :-) -Aug 04 13:30:08 bye -Aug 04 13:30:17 bye -Aug 04 13:30:28 Bye -Aug 04 13:30:36 bye -Aug 04 13:30:40 byebye -Aug 04 13:30:47 bye -Aug 04 13:31:06 <-- arigo (~arigo at arigo.sustaining.supporter.pdpc) has left #pypy-sync -Aug 04 13:31:14 <-- cfbolz (~test at zenon.physi.uni-heidelberg.de) has left #pypy-sync ("Leaving") -Aug 04 13:31:36 <-- nik (~chatzilla at 253.71.77.83.cust.bluewin.ch) has left #pypy-sync -Aug 04 13:31:45 <-- aleale (~chatzilla at clogs.dfki.uni-sb.de) has left #pypy-sync -Aug 04 13:32:16 <-- adim (~adim at logilab.net2.nerim.net) has left #pypy-sync + Aug 04 12:54:29 --> You are now talking on #pypy-sync + Aug 04 12:58:42 should we start? (we're 6 minutes behind already) + Aug 04 12:58:53 ups, my clock says 12:58 + Aug 04 12:59:00 sorry + Aug 04 12:59:04 then sure, let's start right ahead + Aug 04 12:59:06 and hi + Aug 04 12:59:09 hi! + Aug 04 12:59:11 hi + Aug 04 12:59:16 hi :-) + Aug 04 12:59:16 hi + Aug 04 12:59:17 Hi + Aug 04 12:59:20 hi as well + Aug 04 12:59:36 ok, let's go, here is the agenda: + Aug 04 12:59:44 - roll call. + Aug 04 12:59:44 - activity reports (3 prepared lines of info). + Aug 04 12:59:44 - resolve conflicts/blockers + Aug 04 12:59:44 * Topics of the week * + Aug 04 12:59:44 - regularly more closed sprints? + Aug 04 12:59:44 - 0.6.2 release: dropping the idea and just going for 0.7?! + Aug 04 12:59:44 - fixing compliancy bugs + Aug 04 12:59:44 - (re)assignments + Aug 04 13:00:04 (i will be pretending, my clock is right, so it's exactly 13:00 now :-) + Aug 04 13:00:11 activity reports, i supposed the following order: + Aug 04 13:00:11 :-) + Aug 04 13:00:22 rxe,hpk,ericvrp2,nik,adim,arigo,aleale,cfbolz,pedronis,adim + Aug 04 13:00:28 --- You are now known as rxe + Aug 04 13:00:36 LAST: llvm work with Eric (pbc, operations, bpnn, richards, readability of source + Aug 04 13:00:36 NEXT: would be nice to translate pypy itself - not too far off - but will probably be busy wit + Aug 04 13:00:36 h other stuff + Aug 04 13:00:36 BLOCKERS: none + Aug 04 13:00:41 --- You are now known as hpk + Aug 04 13:00:50 LAST: exception handling in llvm backend + Aug 04 13:00:51 NEXT: operator exceptions (divzero,etc) + Aug 04 13:00:51 BLOCKERS: a lot of XXX in llvm backend, might need to refactor first + Aug 04 13:00:55 LAST: hildesheim2-sprint + after-work/reporting, small fixes + cleanup here and there + Aug 04 13:00:55 NEXT: codespeak-migration, (maybe) improve test-report/translation tools + Aug 04 13:00:55 BLOCKERS: time pressure regarding migration + Aug 04 13:01:02 LAST: integrating _sre and array + Aug 04 13:01:10 NEXT: app-level optimizations for _sre, some array improvements. after that (= next week) i'm probably be free for work on general compliance. + Aug 04 13:01:14 BLOCKERS: - + Aug 04 13:01:27 LAST: gave a course + Aug 04 13:01:27 NEXT: continue astbuilder (only since today) + Aug 04 13:01:27 BLOCKERS: no really blockers, byt small problems for some isntructions + Aug 04 13:01:32 --- adim is now known as luda1 + Aug 04 13:01:39 LAST: vacation + Aug 04 13:01:39 NEXT: vacation + Aug 04 13:01:39 BLOCKERS: none + Aug 04 13:01:45 --- luda1 is now known as adim + Aug 04 13:01:52 LAST: fixing bugs in translate_pypy; getting a stand-alone executable instead of an ext module + Aug 04 13:01:52 NEXT: clean-ups (e.g. the Translator class); work on compliance tests; more bugs shown by translate_pypy + Aug 04 13:01:52 BLOCKERS: - + Aug 04 13:01:56 prev: Compliance tests, getting settled in at DFKI + Aug 04 13:01:58 next: Compliance tests + Aug 04 13:01:59 blockers: none + Aug 04 13:02:07 LAST: Hildesheim sprint, lltypesimulation on top of memory simulator, looking ways to integrate lltypesimulation with llinterp + Aug 04 13:02:07 NEXT: integrating lltypesimulation into lltinterp, enhancing llinterp to be able to use simulated GC (finding roots) + Aug 04 13:02:07 BLOCKERS: none + Aug 04 13:02:30 Last: sprint, fix obscure(tm) intermittent annotator problem, fix what prevented "import code" to succeed + Aug 04 13:02:32 Next: work on open issues + Aug 04 13:02:33 Issues: when we try very clever approaches we should try to think of and add sanity checks + Aug 04 13:03:00 ok, that's activity reports, there are no immediate blockers ... + Aug 04 13:03:15 however, we should talk a bit about how to approach compliancy under its own topic + Aug 04 13:03:46 so on to: regularly doing more closed sprints? + Aug 04 13:03:56 Bea mailed me and there were discussions here and there + Aug 04 13:04:06 what do people think about having two types of sprints + Aug 04 13:04:22 like one completely open and more "closed"? + Aug 04 13:04:49 how closed would "closed" be? + Aug 04 13:05:03 I think I only have tried the "closed" one + Aug 04 13:05:29 cfbolz: i'd suggest to define closed as "enough room for the active developers to pair with each other" + Aug 04 13:05:56 because i think that is really the issue, the more newbies or not-up-to-speed people the less the active developers can pair with each other + Aug 04 13:06:01 sounds good :-) + Aug 04 13:06:08 yes + Aug 04 13:06:28 hildesheim was very productive + Aug 04 13:07:04 any other agreeing/disagreeing opinions on this? + Aug 04 13:07:48 Keeping sprints open around conferences seems a good idea, but having more "closed" ones around "deadlines" should be possible too + Aug 04 13:07:56 I think that it goes somewhat against the opensource idea + Aug 04 13:08:19 not really. depends on definition of "active developers" + Aug 04 13:08:21 I would suggest at least 1-2 days for people that might live nearby and want to get the feeling + Aug 04 13:08:33 ericvrp2: i see your point + Aug 04 13:09:03 for example, i am not worried about heidelberg, because there are quite a lot of people registered that know PyPy reasonably well + Aug 04 13:09:28 so if we had 2-4 newbies showing up, that should be quite ok + Aug 04 13:09:54 so by your definition it would even be a closed sprint :-) + Aug 04 13:10:04 cfbolz: psst! :-) + Aug 04 13:11:07 no, I agree. Open would mean something like after EP where really lots of people showed up rather spontaneously + Aug 04 13:11:08 ok, i would like to summarize that the general opinion is that closed sprints are ok, but we want to be careful to a) not do them to often b) not harshly exclude interested developers c) look that we don't go against the open-source spirit + Aug 04 13:11:19 makes sense to always allow nearby people to show up. We should only recommend to other people to fly to an "open" sprint if they have to fly anyway + Aug 04 13:11:37 seems good + Aug 04 13:12:01 fine! + Aug 04 13:12:11 ok for me. + Aug 04 13:12:46 nik: does it also make sense to you? + Aug 04 13:13:08 yep, fine with me + Aug 04 13:13:32 pedronis, aleale: i presume you don't object either (until you do) + Aug 04 13:13:50 correct + Aug 04 13:14:06 * hpk 's clock is 13:14 now + Aug 04 13:14:20 next topic: 0.6.2 release: dropping the idea and just going for 0.7 ... + Aug 04 13:14:27 it's probably uncontroversial + Aug 04 13:14:37 but i want to follow up on earlier discussions/decisions + Aug 04 13:14:54 i guess that we don't go for any 0.6 release anymore and directly tackle 0.7 at heidelberg + Aug 04 13:15:07 everybody fine with this? + Aug 04 13:15:11 yes + Aug 04 13:15:16 what would have been the focus of 0.6.2? + Aug 04 13:15:29 switch to CPython 2.4.1 + Aug 04 13:15:42 i see + Aug 04 13:15:44 nik: compliance, move to 2.4.1 and the parser running on top of cpython both 2.4 and 2.3 + Aug 04 13:16:09 those goals would be shifted to 0.7 + Aug 04 13:16:32 agreed + Aug 04 13:16:38 yes + Aug 04 13:16:50 ok + Aug 04 13:16:54 ok with this + Aug 04 13:17:00 I'm fine with that + Aug 04 13:17:08 great, then the next topic (we still have 13 minutes according to my clock) + Aug 04 13:17:18 Plans for fixing compliancy bugs + Aug 04 13:17:49 there now is a first incomplete text file failure_list.txt in lib-p?ython + Aug 04 13:18:25 the question is a bit a) how we distribute the tasks/analysis + Aug 04 13:18:43 b) how we tackle fixing compliancy issues (adding tests or not?) + Aug 04 13:19:06 c) do we urgently need to count differently then by failing test file? + Aug 04 13:19:22 a) I propose that whoever starts seriously looking at a test, says so in the failure_list.txt + Aug 04 13:19:52 and then he follows up there too when he found the problem, and finally says if/when the problem is fixed or if he can't fix it + Aug 04 13:20:38 b) let's add tests to our own suite unless they are really too obscure + Aug 04 13:20:57 c) I personally don't care too much about counting tests differently + Aug 04 13:21:13 arigo: but the EU might :-) + Aug 04 13:22:01 the revision xxx before the 2.4.1 switch passed 90% of tests + Aug 04 13:22:01 cfbolz: but counting a whole test file just containing one failure as a complete failure is certainly "good for the EU" :-) + Aug 04 13:22:13 do they mandate a figure, like 95% compliancy? + Aug 04 13:22:20 nik: we promised 90% compliancy + Aug 04 13:22:23 hpk: of course :-) + Aug 04 13:23:03 arigo: i agree to a) and b) but regarding c): i think we should prepare for counting differently before heidelberg - just in case + Aug 04 13:23:14 Lets wait until Heidelberg and see if it is needed + Aug 04 13:23:55 hpk: ok + Aug 04 13:24:00 yes, but armin's point is valid as well: no matter how we count, it's annoying that a lot of tests fail now that passed once + Aug 04 13:24:15 cfbolz: i am not even sure about that: 2.4.1 has maybe just added tests? + Aug 04 13:24:36 maybe + Aug 04 13:24:40 that may be true + Aug 04 13:24:44 i noticed several times + Aug 04 13:24:49 that stuff isn't tested in CPython + Aug 04 13:24:49 counting differently sound alot like early optimization to me + Aug 04 13:25:26 ericvrp2: well, we are really counting wrong currently + Aug 04 13:26:02 ericvrp2: consider one test file with 10000 tests all failing, and one test file with 1 test passing -> compkliancy 50% + Aug 04 13:26:52 although most of the time it's really the other way round right now + Aug 04 13:26:54 hpk: I agree with you, but changing that now (unless 5 minutes work) doesn't sound very productive + Aug 04 13:26:59 hpk: fixing the counting should be easy to do at Heidelberg if needed + Aug 04 13:27:21 hpk: I think that time is better spent trying to fix the tests themselves, for now + Aug 04 13:27:51 ok, fine by me (but i still want to to look _a bit_ into the test reporting, anyway, so i might give that a look as well) + Aug 04 13:28:07 sure + Aug 04 13:28:28 there are at least curerntly encoding-problems which prevent test reports + Aug 04 13:28:35 one suggestion: it would help if the whole compliancy suite was run daily on some server + Aug 04 13:28:40 and the results checked in + Aug 04 13:28:54 nik: yes, i had that on codespeak.net but stopped it when the server was getting unstable + Aug 04 13:29:08 ok, i think we have a conclusion on this + Aug 04 13:29:10 hpk: I can do that here, if you give me your script + Aug 04 13:29:20 cfbolz: ok, will tell you off-this-meeting + Aug 04 13:29:27 ok + Aug 04 13:29:36 * hpk is about to close the meeting + Aug 04 13:30:02 thanks all for coming, and see you on the neighbour channel :-) + Aug 04 13:30:05 :-) + Aug 04 13:30:08 bye + Aug 04 13:30:17 bye + Aug 04 13:30:28 Bye + Aug 04 13:30:36 bye + Aug 04 13:30:40 byebye + Aug 04 13:30:47 bye + Aug 04 13:31:06 <-- arigo (~arigo at arigo.sustaining.supporter.pdpc) has left #pypy-sync + Aug 04 13:31:14 <-- cfbolz (~test at zenon.physi.uni-heidelberg.de) has left #pypy-sync ("Leaving") + Aug 04 13:31:36 <-- nik (~chatzilla at 253.71.77.83.cust.bluewin.ch) has left #pypy-sync + Aug 04 13:31:45 <-- aleale (~chatzilla at clogs.dfki.uni-sb.de) has left #pypy-sync + Aug 04 13:32:16 <-- adim (~adim at logilab.net2.nerim.net) has left #pypy-sync From pedronis at codespeak.net Fri Aug 5 00:05:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 00:05:28 +0200 (CEST) Subject: [pypy-svn] r15646 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050804220528.073A227B4D@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 00:04:34 2005 New Revision: 15646 Added: pypy/dist/lib-python/modified-2.4.1/test/list_tests.py - copied, changed from r15639, pypy/dist/lib-python/2.4.1/test/list_tests.py pypy/dist/lib-python/modified-2.4.1/test/seq_tests.py - copied, changed from r15639, pypy/dist/lib-python/2.4.1/test/seq_tests.py pypy/dist/lib-python/modified-2.4.1/test/test_list.py - copied unchanged from r15639, pypy/dist/lib-python/2.4.1/test/test_list.py pypy/dist/lib-python/modified-2.4.1/test/test_tuple.py - copied unchanged from r15639, pypy/dist/lib-python/2.4.1/test/test_tuple.py pypy/dist/lib-python/modified-2.4.1/test/test_userlist.py - copied unchanged from r15639, pypy/dist/lib-python/2.4.1/test/test_userlist.py Log: - made tests on __*slice__ conditional - given that l[Decimal(2)] is not supported the support for .pop seems quite a special case - do we want to support x is x*1 where x is a tuple? - the test about the interaction of __getitem__ and __iter__ is impl specific, the effect of overriding __getitem__ are quite unspecified Copied: pypy/dist/lib-python/modified-2.4.1/test/list_tests.py (from r15639, pypy/dist/lib-python/2.4.1/test/list_tests.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/list_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/list_tests.py Fri Aug 5 00:04:34 2005 @@ -178,9 +178,10 @@ a[:] = tuple(range(10)) self.assertEqual(a, self.type2test(range(10))) - self.assertRaises(TypeError, a.__setslice__, 0, 1, 5) + if hasattr(a, '__setslice__'): + self.assertRaises(TypeError, a.__setslice__, 0, 1, 5) - self.assertRaises(TypeError, a.__setslice__) + self.assertRaises(TypeError, a.__setslice__) def test_delslice(self): a = self.type2test([0, 1]) @@ -281,8 +282,10 @@ self.assertRaises(IndexError, a.pop) self.assertRaises(TypeError, a.pop, 42, 42) a = self.type2test([0, 10, 20, 30, 40]) - self.assertEqual(a.pop(Decimal(2)), 20) - self.assertRaises(IndexError, a.pop, Decimal(25)) + # xxx Decimal make a bad index as much as float + # also l[Decimal(2)] doesn't work, what to make of this? + #self.assertEqual(a.pop(Decimal(2)), 20) + #self.assertRaises(IndexError, a.pop, Decimal(25)) def test_remove(self): a = self.type2test([0, 0, 1]) Copied: pypy/dist/lib-python/modified-2.4.1/test/seq_tests.py (from r15639, pypy/dist/lib-python/2.4.1/test/seq_tests.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/seq_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/seq_tests.py Fri Aug 5 00:04:34 2005 @@ -106,7 +106,8 @@ self.assertEqual(a[ -pow(2,128L): 3 ], self.type2test([0,1,2])) self.assertEqual(a[ 3: pow(2,145L) ], self.type2test([3,4])) - self.assertRaises(TypeError, u.__getslice__) + if hasattr(u, '__getslice__'): + self.assertRaises(TypeError, u.__getslice__) def test_contains(self): u = self.type2test([0, 1, 2]) @@ -174,12 +175,12 @@ u *= 3 self.assertEqual(u, self.type2test([0, 1, 0, 1, 0, 1])) - def test_getitemoverwriteiter(self): - # Verify that __getitem__ overrides are not recognized by __iter__ - class T(self.type2test): - def __getitem__(self, key): - return str(key) + '!!!' - self.assertEqual(iter(T((1,2))).next(), 1) + #def test_getitemoverwriteiter(self): + # # Verify that __getitem__ overrides are not recognized by __iter__ + # class T(self.type2test): + # def __getitem__(self, key): + # return str(key) + '!!!' + # self.assertEqual(iter(T((1,2))).next(), 1) def test_repeat(self): for m in xrange(4): @@ -187,7 +188,7 @@ for n in xrange(-3, 5): self.assertEqual(self.type2test(s*n), self.type2test(s)*n) self.assertEqual(self.type2test(s)*(-4), self.type2test([])) - self.assertEqual(id(s), id(s*1)) + #self.assertEqual(id(s), id(s*1)) def test_subscript(self): a = self.type2test([10, 11]) From pedronis at codespeak.net Fri Aug 5 00:13:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 00:13:13 +0200 (CEST) Subject: [pypy-svn] r15648 - pypy/dist/lib-python Message-ID: <20050804221313.E5DAB27B4B@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 00:13:08 2005 New Revision: 15648 Modified: pypy/dist/lib-python/failure_list.txt Log: updated Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 00:13:08 2005 @@ -27,4 +27,8 @@ - disallow interning of string subclasses - __future__ import division problems -test_new FIXED \ No newline at end of file + +test_tuple etc + do we want to support x is x*1 where is exactly a tuple? + +test_new FIXED From pedronis at codespeak.net Fri Aug 5 00:17:23 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 00:17:23 +0200 (CEST) Subject: [pypy-svn] r15649 - pypy/dist/lib-python Message-ID: <20050804221723.6401227B4B@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 00:17:21 2005 New Revision: 15649 Modified: pypy/dist/lib-python/failure_list.txt Log: oops Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 00:17:21 2005 @@ -29,6 +29,6 @@ test_tuple etc - do we want to support x is x*1 where is exactly a tuple? + do we want to support x is x*1 where x is exactly a tuple? test_new FIXED From arigo at codespeak.net Fri Aug 5 00:41:06 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 00:41:06 +0200 (CEST) Subject: [pypy-svn] r15650 - pypy/dist/pypy/translator/goal Message-ID: <20050804224106.4455A27B4D@code1.codespeak.net> Author: arigo Date: Fri Aug 5 00:41:05 2005 New Revision: 15650 Modified: pypy/dist/pypy/translator/goal/runtranslate.sh Log: This version translates and builds a stand-alone executable. Modified: pypy/dist/pypy/translator/goal/runtranslate.sh ============================================================================== --- pypy/dist/pypy/translator/goal/runtranslate.sh (original) +++ pypy/dist/pypy/translator/goal/runtranslate.sh Fri Aug 5 00:41:05 2005 @@ -2,7 +2,7 @@ # stopping on the first error #python translate_pypy.py -no-c -no-o -text -no-snapshot -fork # running it all -python translate_pypy.py -no-o -text -t-insist -no-snapshot $* +python translate_pypy.py targetpypystandalone -text -no-snapshot $* # How to work in parallel: From arigo at codespeak.net Fri Aug 5 01:46:35 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 01:46:35 +0200 (CEST) Subject: [pypy-svn] r15652 - in pypy/dist/pypy: module/posix rpython translator/c translator/c/src Message-ID: <20050804234635.C338327B4B@code1.codespeak.net> Author: arigo Date: Fri Aug 5 01:46:32 2005 New Revision: 15652 Modified: pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/src/ll_time.h pypy/dist/pypy/translator/c/src/standalone.h Log: Tentative Windows compatibility (thanks xorAxAx): * remove all references to os.ftruncate() for Windows * disabled (for now) complicated code in time.sleep() * pragma to disable the most common warnings * #including Python.h is enough to pull in libraries, needs to be more careful (#define Py_BUILD_CORE) * infinite floats: literal 1E9999999 is not accepted, the IEEE-only expression (1E200*1E200) works. Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Fri Aug 5 01:46:32 2005 @@ -21,11 +21,13 @@ 'isatty' : 'interp_posix.isatty', 'read' : 'interp_posix.read', 'close' : 'interp_posix.close', - 'ftruncate' : 'interp_posix.ftruncate', 'fstat' : 'interp_posix.fstat', 'stat' : 'interp_posix.stat', 'dup' : 'interp_posix.dup', } + if hasattr(os, 'ftruncate'): + interpleveldefs['ftruncate'] = 'interp_posix.ftruncate' + for constant in ['EX_CANTCREAT', 'EX_CONFIG', 'EX_DATAERR', 'EX_IOERR', 'EX_NOHOST', 'EX_NOINPUT', 'EX_NOPERM', 'EX_NOUSER', Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Fri Aug 5 01:46:32 2005 @@ -75,11 +75,8 @@ declare(os.dup , int , 'll_os/dup') declare(os.lseek , int , 'll_os/lseek') declare(os.isatty , bool , 'll_os/isatty') -try: - os.ftruncate # yes, this is a hack for windows, please make it better -except AttributeError: - os.ftruncate = lambda f: None -declare(os.ftruncate, noneannotation, 'll_os/ftruncate') +if hasattr(os, 'ftruncate'): + declare(os.ftruncate, noneannotation, 'll_os/ftruncate') declare(os.fstat , statannotation, 'll_os/fstat') declare(os.stat , statannotation, 'll_os/stat') declare(os.strerror , str , 'll_os/strerror') Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Fri Aug 5 01:46:32 2005 @@ -20,10 +20,13 @@ def name_float(value): if isinf(value): + # the following seems to produce an inf both on gcc and MS compilers + # XXX but it depends on the size of the doubles + assert isinf(1E200*1E200) if value > 0: - return '1E9999999' + return '(1E200*1E200)' else: - return '-1E9999999' + return '(-1E200*1E200)' else: return repr(value) Modified: pypy/dist/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_include.h (original) +++ pypy/dist/pypy/translator/c/src/g_include.h Fri Aug 5 01:46:32 2005 @@ -2,12 +2,8 @@ /************************************************************/ /*** C header file for code produced by genc.py ***/ -/* 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 - */ -#include "Python.h" #ifndef PYPY_STANDALONE +# include "Python.h" # include "compile.h" # include "frameobject.h" # include "structmember.h" Modified: pypy/dist/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_os.h (original) +++ pypy/dist/pypy/translator/c/src/ll_os.h Fri Aug 5 01:46:32 2005 @@ -164,6 +164,7 @@ return (int)isatty((int)fd); } +#ifdef HAVE_FTRUNCATE void LL_os_ftruncate(long fd, long length) { /*XXX add longfile support */ int res; res = ftruncate((int)fd, (off_t)length); @@ -171,6 +172,7 @@ RAISE_OSERROR(errno); } } +#endif RPyString *LL_os_strerror(int errnum) { Modified: pypy/dist/pypy/translator/c/src/ll_time.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_time.h (original) +++ pypy/dist/pypy/translator/c/src/ll_time.h Fri Aug 5 01:46:32 2005 @@ -63,21 +63,22 @@ return; } ul_millis = (unsigned long)millisecs; - if (ul_millis == 0) + /* XXX copy CPython to make this interruptible again */ + /*if (ul_millis == 0)*/ Sleep(ul_millis); - else { + /*else { DWORD rc; ResetEvent(hInterruptEvent); rc = WaitForSingleObject(hInterruptEvent, ul_millis); if (rc == WAIT_OBJECT_0) { - /* Yield to make sure real Python signal + * Yield to make sure real Python signal * handler called. - */ + * Sleep(1); RaiseSimpleException(Exc_IOError, "interrupted"); return; } - } + }*/ #else struct timeval t; double frac; Modified: pypy/dist/pypy/translator/c/src/standalone.h ============================================================================== --- pypy/dist/pypy/translator/c/src/standalone.h (original) +++ pypy/dist/pypy/translator/c/src/standalone.h Fri Aug 5 01:46:32 2005 @@ -1,3 +1,10 @@ +/* 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 + */ +#define Py_BUILD_CORE /* for Windows: avoid pulling libs in */ +#include "Python.h" + #include #include #include @@ -6,3 +13,8 @@ #define PyObject_Malloc malloc #define PyObject_Free free +#ifdef MS_WINDOWS +# ifdef _MSC_VER +# pragma warning(disable: 4033 4102 4101 4716) /*suppress a few warnings*/ +# endif +#endif From arigo at codespeak.net Fri Aug 5 11:46:31 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 11:46:31 +0200 (CEST) Subject: [pypy-svn] r15659 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050805094631.39A9D27B47@code1.codespeak.net> Author: arigo Date: Fri Aug 5 11:46:27 2005 New Revision: 15659 Added: pypy/dist/lib-python/modified-2.4.1/test/test_optparse.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/test_optparse.py Log: test_optparse depended on dictionary key order. Copied: pypy/dist/lib-python/modified-2.4.1/test/test_optparse.py (from r15656, pypy/dist/lib-python/2.4.1/test/test_optparse.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_optparse.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_optparse.py Fri Aug 5 11:46:27 2005 @@ -211,9 +211,11 @@ ["---"]) def test_attr_invalid(self): + d = {'foo': None, 'bar': None} + msg = ', '.join(d.keys()) self.assertOptionError( - "option -b: invalid keyword arguments: foo, bar", - ["-b"], {'foo': None, 'bar': None}) + "option -b: invalid keyword arguments: %s" % msg, + ["-b"], d) def test_action_invalid(self): self.assertOptionError( From arigo at codespeak.net Fri Aug 5 11:54:13 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 11:54:13 +0200 (CEST) Subject: [pypy-svn] r15660 - pypy/dist/pypy/translator/c/src Message-ID: <20050805095413.B763327B47@code1.codespeak.net> Author: arigo Date: Fri Aug 5 11:54:10 2005 New Revision: 15660 Modified: pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/c/src/standalone.h Log: (xorAxAx) we can put the warning suppression into the normal processing path as well; those warnings are not standalone-only. Modified: pypy/dist/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_include.h (original) +++ pypy/dist/pypy/translator/c/src/g_include.h Fri Aug 5 11:54:10 2005 @@ -41,3 +41,9 @@ # include "src/main.h" #endif +/* suppress a few warnings in the generated code */ +#ifdef MS_WINDOWS +# ifdef _MSC_VER +# pragma warning(disable: 4033 4102 4101 4716) +# endif +#endif Modified: pypy/dist/pypy/translator/c/src/standalone.h ============================================================================== --- pypy/dist/pypy/translator/c/src/standalone.h (original) +++ pypy/dist/pypy/translator/c/src/standalone.h Fri Aug 5 11:54:10 2005 @@ -12,9 +12,3 @@ #define PyObject_Malloc malloc #define PyObject_Free free - -#ifdef MS_WINDOWS -# ifdef _MSC_VER -# pragma warning(disable: 4033 4102 4101 4716) /*suppress a few warnings*/ -# endif -#endif From arigo at codespeak.net Fri Aug 5 11:56:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 11:56:43 +0200 (CEST) Subject: [pypy-svn] r15661 - pypy/dist/lib-python Message-ID: <20050805095643.1022527B50@code1.codespeak.net> Author: arigo Date: Fri Aug 5 11:56:40 2005 New Revision: 15661 Modified: pypy/dist/lib-python/failure_list.txt Log: Mention test_extcall. Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 11:56:40 2005 @@ -32,3 +32,7 @@ do we want to support x is x*1 where x is exactly a tuple? test_new FIXED + +test_extcall + cannot be fixed. PyPy produces different TypeError messages but they are + also correct and useful (reviewed them again). From arigo at codespeak.net Fri Aug 5 12:18:34 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 12:18:34 +0200 (CEST) Subject: [pypy-svn] r15665 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050805101834.9AFF927B47@code1.codespeak.net> Author: arigo Date: Fri Aug 5 12:18:31 2005 New Revision: 15665 Modified: pypy/dist/pypy/objspace/std/dictobject.py pypy/dist/pypy/objspace/std/test/test_dictobject.py pypy/dist/pypy/objspace/std/test/test_dictproxy.py Log: Dicts should not have __str__(). A test depends on being able to override __repr__ in a subclass and have it called by str(). Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Fri Aug 5 12:18:31 2005 @@ -275,7 +275,7 @@ return w_default app = gateway.applevel(''' - def dictstr(currently_in_repr, d): + def dictrepr(currently_in_repr, d): # Now we only handle one implementation of dicts, this one. # The fix is to move this to dicttype.py, and do a # multimethod lookup mapping str to StdObjSpace.str @@ -296,15 +296,13 @@ pass ''', filename=__file__) -dictstr = app.interphook("dictstr") +dictrepr = app.interphook("dictrepr") -def str__Dict(space, w_dict): +def repr__Dict(space, w_dict): if w_dict.used == 0: return space.wrap('{}') w_currently_in_repr = space.getexecutioncontext()._py_repr - return dictstr(space, w_currently_in_repr, w_dict) - -repr__Dict = str__Dict + return dictrepr(space, w_currently_in_repr, w_dict) # ____________________________________________________________ Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictobject.py Fri Aug 5 12:18:31 2005 @@ -309,6 +309,13 @@ assert {1: 0, 2: 0, 3: 0}.fromkeys([1, '1'], 'j') == ( {1: 'j', '1': 'j'}) + def test_str_uses_repr(self): + class D(dict): + def __repr__(self): + return 'hi' + assert repr(D()) == 'hi' + assert str(D()) == 'hi' + # the minimal 'space' needed to use a W_DictObject class FakeSpace: def hash(self, obj): Modified: pypy/dist/pypy/objspace/std/test/test_dictproxy.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictproxy.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictproxy.py Fri Aug 5 12:18:31 2005 @@ -30,3 +30,11 @@ assert a.__dict__ != {'123': '456'} assert {'123': '456'} != a.__dict__ assert b.__dict__ == c.__dict__ + + def test_str_repr(self): + class a(object): + pass + s = repr(a.__dict__) + assert s.startswith('') + s = str(a.__dict__) + assert s.startswith('{') and s.endswith('}') From arigo at codespeak.net Fri Aug 5 12:18:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 12:18:43 +0200 (CEST) Subject: [pypy-svn] r15666 - pypy/dist/lib-python Message-ID: <20050805101843.8437927B51@code1.codespeak.net> Author: arigo Date: Fri Aug 5 12:18:41 2005 New Revision: 15666 Modified: pypy/dist/lib-python/failure_list.txt Log: Progress... Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 12:18:41 2005 @@ -36,3 +36,9 @@ test_extcall cannot be fixed. PyPy produces different TypeError messages but they are also correct and useful (reviewed them again). + +test_optparse FIXED? + +test_mutants FIXED? + overriding __repr__ in a dict subclass doesn't change the str(). + The dict class should not have an __str__ of its own. From arigo at codespeak.net Fri Aug 5 12:37:38 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 12:37:38 +0200 (CEST) Subject: [pypy-svn] r15667 - pypy/dist/pypy/objspace/std Message-ID: <20050805103738.54FDA27B41@code1.codespeak.net> Author: arigo Date: Fri Aug 5 12:37:35 2005 New Revision: 15667 Modified: pypy/dist/pypy/objspace/std/listobject.py Log: Slight changes in the way list.sort() detects changes. This ordering looks better and is closer to what CPython does. Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Fri Aug 5 12:37:35 2005 @@ -650,10 +650,9 @@ # perform the sort sorter.sort() - # check if the user mucked with the list during the sort - if w_list.ob_item: - raise OperationError(space.w_ValueError, - space.wrap("list modified during sort")) + # reverse again + if has_reverse: + _reverse_slice(sorter.list, 0, sorter.listlength) finally: # unwrap each item if needed @@ -663,13 +662,17 @@ if isinstance(w_obj, KeyContainer): sorter.list[i] = w_obj.w_item - if has_reverse: - _reverse_slice(sorter.list, 0, sorter.listlength) + # check if the user mucked with the list during the sort + mucked = len(w_list.ob_item) > 0 # put the items back into the list w_list.ob_item = sorter.list w_list.ob_size = sorter.listlength + if mucked: + raise OperationError(space.w_ValueError, + space.wrap("list modified during sort")) + return space.w_None From arigo at codespeak.net Fri Aug 5 12:38:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 12:38:46 +0200 (CEST) Subject: [pypy-svn] r15668 - pypy/dist/lib-python Message-ID: <20050805103846.8722227B41@code1.codespeak.net> Author: arigo Date: Fri Aug 5 12:38:44 2005 New Revision: 15668 Modified: pypy/dist/lib-python/failure_list.txt Log: test_sort fixed? Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 12:38:44 2005 @@ -42,3 +42,7 @@ test_mutants FIXED? overriding __repr__ in a dict subclass doesn't change the str(). The dict class should not have an __str__ of its own. + +test_sort FIXED? + different way of detecting mutations during sort: PyPy didn't detect + changes done by the __del__ method of the key-wrapper objects. From arigo at codespeak.net Fri Aug 5 13:05:15 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 13:05:15 +0200 (CEST) Subject: [pypy-svn] r15672 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050805110515.A38EB27B47@code1.codespeak.net> Author: arigo Date: Fri Aug 5 13:05:10 2005 New Revision: 15672 Added: pypy/dist/lib-python/modified-2.4.1/test/pickletester.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/pickletester.py pypy/dist/lib-python/modified-2.4.1/test/string_tests.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/string_tests.py Log: Porting these files from modified-2.3.4/test/. Copied: pypy/dist/lib-python/modified-2.4.1/test/pickletester.py (from r15656, pypy/dist/lib-python/2.4.1/test/pickletester.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/pickletester.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/pickletester.py Fri Aug 5 13:05:10 2005 @@ -1,3 +1,9 @@ +# Notes about changes in this file: +# a prefix of "dont_" means the test makes no sense, +# because we don't use cPickle at all. +# "xxx_" means it works and can be done, but takes ages. +# When PyPy gets really fast, we should remove "xxx_". + import unittest import pickle import cPickle @@ -508,7 +514,7 @@ data = 'I' + str(maxint64) + 'JUNK\n.' self.assertRaises(ValueError, self.loads, data) - def test_long(self): + def xxx_test_long(self): for proto in protocols: # 256 bytes is where LONG4 begins. for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257: @@ -733,7 +739,7 @@ self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness - def test_list_chunking(self): + def xxx_test_list_chunking(self): n = 10 # too small to chunk x = range(n) for proto in protocols: @@ -755,7 +761,7 @@ else: self.failUnless(num_appends >= 2) - def test_dict_chunking(self): + def xxx_test_dict_chunking(self): n = 10 # too small to chunk x = dict.fromkeys(range(n)) for proto in protocols: Copied: pypy/dist/lib-python/modified-2.4.1/test/string_tests.py (from r15656, pypy/dist/lib-python/2.4.1/test/string_tests.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/string_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/string_tests.py Fri Aug 5 13:05:10 2005 @@ -2,7 +2,7 @@ Common tests shared by test_str, test_unicode, test_userstring and test_string. """ -import unittest, string, sys +import unittest, string, sys, operator from test import test_support from UserList import UserList @@ -64,6 +64,16 @@ realresult = getattr(object, methodname)(*args) self.assert_(object is not realresult) + # check that op(*args) returns result + def checkop(self, result, op, *args): + result = self.fixtype(result) + args = self.fixtype(args) + realresult = op(*args) + self.assertEqual( + result, + realresult + ) + # check that object.method(*args) raises exc def checkraises(self, exc, object, methodname, *args): object = self.fixtype(object) @@ -74,12 +84,26 @@ *args ) + # check that op(*args) raises exc + def checkopraises(self, exc, op, *args): + args = self.fixtype(args) + self.assertRaises( + exc, + op, + *args + ) + # call object.method(*args) without any checks def checkcall(self, object, methodname, *args): object = self.fixtype(object) args = self.fixtype(args) getattr(object, methodname)(*args) + # call op(*args) without any checks + def checkopcall(self, op, *args): + args = self.fixtype(args) + op(*args) + def test_hash(self): # SF bug 1054139: += optimization was not invalidating cached hash value a = self.type2test('DNSSEC') @@ -532,50 +556,50 @@ self.checkraises(TypeError, 'hello', 'endswith', 42) def test___contains__(self): - self.checkequal(True, '', '__contains__', '') # vereq('' in '', True) - self.checkequal(True, 'abc', '__contains__', '') # vereq('' in 'abc', True) - self.checkequal(False, 'abc', '__contains__', '\0') # vereq('\0' in 'abc', False) - self.checkequal(True, '\0abc', '__contains__', '\0') # vereq('\0' in '\0abc', True) - self.checkequal(True, 'abc\0', '__contains__', '\0') # vereq('\0' in 'abc\0', True) - self.checkequal(True, '\0abc', '__contains__', 'a') # vereq('a' in '\0abc', True) - self.checkequal(True, 'asdf', '__contains__', 'asdf') # vereq('asdf' in 'asdf', True) - self.checkequal(False, 'asd', '__contains__', 'asdf') # vereq('asdf' in 'asd', False) - self.checkequal(False, '', '__contains__', 'asdf') # vereq('asdf' in '', False) + self.checkop(True, operator.contains, '', '') # vereq('' in '', True) + self.checkop(True, operator.contains, 'abc', '') # vereq('' in 'abc', True) + self.checkop(False, operator.contains, 'abc', '\0') # vereq('\0' in 'abc', False) + self.checkop(True, operator.contains, '\0abc', '\0') # vereq('\0' in '\0abc', True) + self.checkop(True, operator.contains, 'abc\0', '\0') # vereq('\0' in 'abc\0', True) + self.checkop(True, operator.contains, '\0abc', 'a') # vereq('a' in '\0abc', True) + self.checkop(True, operator.contains, 'asdf', 'asdf') # vereq('asdf' in 'asdf', True) + self.checkop(False, operator.contains, 'asd', 'asdf') # vereq('asdf' in 'asd', False) + self.checkop(False, operator.contains, '', 'asdf') # vereq('asdf' in '', False) def test_subscript(self): - self.checkequal(u'a', 'abc', '__getitem__', 0) - self.checkequal(u'c', 'abc', '__getitem__', -1) - self.checkequal(u'a', 'abc', '__getitem__', 0L) - self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 3)) - self.checkequal(u'abc', 'abc', '__getitem__', slice(0, 1000)) - self.checkequal(u'a', 'abc', '__getitem__', slice(0, 1)) - self.checkequal(u'', 'abc', '__getitem__', slice(0, 0)) + self.checkop(u'a', operator.getitem, 'abc', 0) + self.checkop(u'c', operator.getitem, 'abc', -1) + self.checkop(u'a', operator.getitem, 'abc', 0L) + self.checkop(u'abc', operator.getitem, 'abc', slice(0, 3)) + self.checkop(u'abc', operator.getitem, 'abc', slice(0, 1000)) + self.checkop(u'a', operator.getitem, 'abc', slice(0, 1)) + self.checkop(u'', operator.getitem, 'abc', slice(0, 0)) # FIXME What about negative indizes? This is handled differently by [] and __getitem__(slice) - self.checkraises(TypeError, 'abc', '__getitem__', 'def') + self.checkopraises(TypeError, operator.getitem, 'abc', 'def') def test_slice(self): - self.checkequal('abc', 'abc', '__getslice__', 0, 1000) - self.checkequal('abc', 'abc', '__getslice__', 0, 3) - self.checkequal('ab', 'abc', '__getslice__', 0, 2) - self.checkequal('bc', 'abc', '__getslice__', 1, 3) - self.checkequal('b', 'abc', '__getslice__', 1, 2) - self.checkequal('', 'abc', '__getslice__', 2, 2) - self.checkequal('', 'abc', '__getslice__', 1000, 1000) - self.checkequal('', 'abc', '__getslice__', 2000, 1000) - self.checkequal('', 'abc', '__getslice__', 2, 1) + self.checkop('abc', operator.getslice, 'abc', 0, 1000) + self.checkop('abc', operator.getslice, 'abc', 0, 3) + self.checkop('ab', operator.getslice, 'abc', 0, 2) + self.checkop('bc', operator.getslice, 'abc', 1, 3) + self.checkop('b', operator.getslice, 'abc', 1, 2) + self.checkop('', operator.getslice, 'abc', 2, 2) + self.checkop('', operator.getslice, 'abc', 1000, 1000) + self.checkop('', operator.getslice, 'abc', 2000, 1000) + self.checkop('', operator.getslice, 'abc', 2, 1) # FIXME What about negative indizes? This is handled differently by [] and __getslice__ - self.checkraises(TypeError, 'abc', '__getslice__', 'def') + self.checkopraises(TypeError, operator.getslice, 'abc', 'def') def test_mul(self): - self.checkequal('', 'abc', '__mul__', -1) - self.checkequal('', 'abc', '__mul__', 0) - self.checkequal('abc', 'abc', '__mul__', 1) - self.checkequal('abcabcabc', 'abc', '__mul__', 3) - self.checkraises(TypeError, 'abc', '__mul__') - self.checkraises(TypeError, 'abc', '__mul__', '') - self.checkraises(OverflowError, 10000*'abc', '__mul__', 2000000000) + self.checkop('', operator.mul, 'abc', -1) + self.checkop('', operator.mul, 'abc', 0) + self.checkop('abc', operator.mul, 'abc', 1) + self.checkop('abcabcabc', operator.mul, 'abc', 3) + self.checkopraises(TypeError, operator.mul, 'abc') + self.checkopraises(TypeError, operator.mul, 'abc', '') + self.checkopraises(OverflowError, operator.mul, 10000*'abc', 2000000000) def test_join(self): # join now works with any sequence type @@ -607,55 +631,57 @@ self.checkraises(TypeError, ' ', 'join', Sequence([7, 'hello', 123L])) def test_formatting(self): - self.checkequal('+hello+', '+%s+', '__mod__', 'hello') - self.checkequal('+10+', '+%d+', '__mod__', 10) - self.checkequal('a', "%c", '__mod__', "a") - self.checkequal('a', "%c", '__mod__', "a") - self.checkequal('"', "%c", '__mod__', 34) - self.checkequal('$', "%c", '__mod__', 36) - self.checkequal('10', "%d", '__mod__', 10) - self.checkequal('\x7f', "%c", '__mod__', 0x7f) + self.checkop('+hello+', operator.mod, '+%s+', 'hello') + self.checkop('+10+', operator.mod, '+%d+', 10) + self.checkop('a', operator.mod, "%c", "a") + self.checkop('a', operator.mod, "%c", "a") + self.checkop('"', operator.mod, "%c", 34) + self.checkop('$', operator.mod, "%c", 36) + self.checkop('10', operator.mod, "%d", 10) + self.checkop('\x7f', operator.mod, "%c", 0x7f) for ordinal in (-100, 0x200000): # unicode raises ValueError, str raises OverflowError - self.checkraises((ValueError, OverflowError), '%c', '__mod__', ordinal) + self.checkopraises((ValueError, OverflowError), operator.mod, '%c', ordinal) - self.checkequal(' 42', '%3ld', '__mod__', 42) - self.checkequal('0042.00', '%07.2f', '__mod__', 42) - self.checkequal('0042.00', '%07.2F', '__mod__', 42) - - self.checkraises(TypeError, 'abc', '__mod__') - self.checkraises(TypeError, '%(foo)s', '__mod__', 42) - self.checkraises(TypeError, '%s%s', '__mod__', (42,)) - self.checkraises(TypeError, '%c', '__mod__', (None,)) - self.checkraises(ValueError, '%(foo', '__mod__', {}) - self.checkraises(TypeError, '%(foo)s %(bar)s', '__mod__', ('foo', 42)) + self.checkop(' 42', operator.mod, '%3ld', 42) + self.checkop('0042.00', operator.mod, '%07.2f', 42) + self.checkop('0042.00', operator.mod, '%07.2F', 42) + + self.checkopraises(TypeError, operator.mod, 'abc') + self.checkopraises(TypeError, operator.mod, '%(foo)s', 42) + self.checkopraises(TypeError, operator.mod, '%s%s', (42,)) + self.checkopraises(TypeError, operator.mod, '%c', (None,)) + self.checkopraises(ValueError, operator.mod, '%(foo', {}) + self.checkopraises(TypeError, operator.mod, '%(foo)s %(bar)s', ('foo', 42)) # argument names with properly nested brackets are supported - self.checkequal('bar', '%((foo))s', '__mod__', {'(foo)': 'bar'}) + self.checkop('bar', operator.mod, '%((foo))s', {'(foo)': 'bar'}) # 100 is a magic number in PyUnicode_Format, this forces a resize - self.checkequal(103*'a'+'x', '%sx', '__mod__', 103*'a') + self.checkop(103*'a'+'x', operator.mod, '%sx', 103*'a') - self.checkraises(TypeError, '%*s', '__mod__', ('foo', 'bar')) - self.checkraises(TypeError, '%10.*f', '__mod__', ('foo', 42.)) - self.checkraises(ValueError, '%10', '__mod__', (42,)) + self.checkopraises(TypeError, operator.mod, '%*s', ('foo', 'bar')) + self.checkopraises(TypeError, operator.mod, '%10.*f', ('foo', 42.)) + self.checkopraises(ValueError, operator.mod, '%10', (42,)) def test_floatformatting(self): # float formatting - for prec in xrange(100): + # XXX changed for PyPy to be faster + for prec, value in [(0, 3.141592655), + (1, 0.01), + (2, 120394), + (5, 23.01958), + (20, 141414.51321098), + (49, 0.01), + (50, 1e50), + (99, 123)]: format = '%%.%if' % prec - value = 0.01 - for x in xrange(60): - value = value * 3.141592655 / 3.0 * 10.0 - # The formatfloat() code in stringobject.c and - # unicodeobject.c uses a 120 byte buffer and switches from - # 'f' formatting to 'g' at precision 50, so we expect - # OverflowErrors for the ranges x < 50 and prec >= 67. - if x < 50 and prec >= 67: - self.checkraises(OverflowError, format, "__mod__", value) - else: - self.checkcall(format, "__mod__", value) + try: + self.checkopcall(operator.mod, format, value) + except OverflowError: + self.failUnless(abs(value) < 1e25 and prec >= 67, + "OverflowError on small examples") class MixinStrStringUserStringTest: From pedronis at codespeak.net Fri Aug 5 13:26:39 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 13:26:39 +0200 (CEST) Subject: [pypy-svn] r15674 - pypy/dist/lib-python Message-ID: <20050805112639.95C0427B47@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 13:26:38 2005 New Revision: 15674 Modified: pypy/dist/lib-python/failure_list.txt Log: test_optparse passes Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 13:26:38 2005 @@ -37,7 +37,7 @@ cannot be fixed. PyPy produces different TypeError messages but they are also correct and useful (reviewed them again). -test_optparse FIXED? +test_optparse FIXED test_mutants FIXED? overriding __repr__ in a dict subclass doesn't change the str(). From cfbolz at codespeak.net Fri Aug 5 13:27:02 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 5 Aug 2005 13:27:02 +0200 (CEST) Subject: [pypy-svn] r15675 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050805112702.932B027B47@code1.codespeak.net> Author: cfbolz Date: Fri Aug 5 13:27:01 2005 New Revision: 15675 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: fixed arrays of ptrs + test Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Fri Aug 5 13:27:01 2005 @@ -48,7 +48,7 @@ elif isinstance(TYPE, lltype.Primitive): return 0 elif isinstance(TYPE, lltype.Struct): - if isinstance(TYPE._flds[TYPE._names[-1]], lltype.Array): + if TYPE._arrayfld is not None: return get_variable_size(TYPE._flds[TYPE._arrayfld]) else: return 0 @@ -71,6 +71,8 @@ return simulatorptr(lltype.Ptr(T), address) elif isinstance(T, lltype.Primitive): return address._load(primitive_to_fmt[T])[0] + elif isinstance(T, lltype.Ptr): + return simulatorptr(T, address) else: assert 0, "not implemented yet" @@ -156,6 +158,8 @@ " got %r" % (self._T, T1, T2)) if not (0 <= i < self._address.signed[0]): raise IndexError, "array index out of bounds" + if isinstance(T2, lltype.Ptr): + value = value._address.intaddress addr = self._address + self._layout[0] + i * self._layout[1] addr._store(get_layout(self._T.OF), value) return Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Fri Aug 5 13:27:01 2005 @@ -225,6 +225,18 @@ s = malloc(S) py.test.raises(TypeError, "a[0] = s") +def test_array_of_ptrs(): + S = lltype.GcStruct("name", ("v", lltype.Signed)) + A = lltype.GcArray(lltype.Ptr(S)) + a = malloc(A, 3) + a[0] = malloc(S) + a[0].v = 1 + a[1] = malloc(S) + a[1].v = 2 + a[2] = malloc(S) + a[2].v = 3 + assert [a[z].v for z in range(3)] == [1, 2, 3] + def DONOTtest_getRuntimeTypeInfo(): S = GcStruct('s', ('x', Signed)) py.test.raises(ValueError, "getRuntimeTypeInfo(S)") From arigo at codespeak.net Fri Aug 5 13:28:01 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 13:28:01 +0200 (CEST) Subject: [pypy-svn] r15676 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050805112801.A91B827B47@code1.codespeak.net> Author: arigo Date: Fri Aug 5 13:27:50 2005 New Revision: 15676 Added: pypy/dist/lib-python/modified-2.4.1/test/test_complex.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/test_complex.py pypy/dist/lib-python/modified-2.4.1/test/test_cpickle.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/test_cpickle.py pypy/dist/lib-python/modified-2.4.1/test/test_descr.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/test_descr.py Log: More porting from modified-2.3.4... Copied: pypy/dist/lib-python/modified-2.4.1/test/test_complex.py (from r15656, pypy/dist/lib-python/2.4.1/test/test_complex.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_complex.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_complex.py Fri Aug 5 13:27:50 2005 @@ -68,7 +68,8 @@ self.assertClose(q, x) def test_div(self): - simple_real = [float(i) for i in xrange(-5, 6)] + # too slow for PyPy --- simple_real = [float(i) for i in xrange(-5, 6)] + simple_real = [-2.0, 0.0, 1.0] simple_complex = [complex(x, y) for x in simple_real for y in simple_real] for x in simple_complex: for y in simple_complex: Copied: pypy/dist/lib-python/modified-2.4.1/test/test_cpickle.py (from r15656, pypy/dist/lib-python/2.4.1/test/test_cpickle.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_cpickle.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_cpickle.py Fri Aug 5 13:27:50 2005 @@ -1,7 +1,7 @@ import cPickle import unittest from cStringIO import StringIO -from pickletester import AbstractPickleTests, AbstractPickleModuleTests +from test.pickletester import AbstractPickleTests, AbstractPickleModuleTests from test import test_support class cPickleTests(AbstractPickleTests, AbstractPickleModuleTests): Copied: pypy/dist/lib-python/modified-2.4.1/test/test_descr.py (from r15656, pypy/dist/lib-python/2.4.1/test/test_descr.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_descr.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_descr.py Fri Aug 5 13:27:50 2005 @@ -20,7 +20,7 @@ m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - vereq(m, t.__dict__[meth]) + vereq(t.__dict__[meth](a), res) vereq(m(a), res) bm = getattr(a, meth) vereq(bm(), res) @@ -38,7 +38,7 @@ m = getattr(t, meth) while meth not in t.__dict__: t = t.__bases__[0] - vereq(m, t.__dict__[meth]) + vereq(t.__dict__[meth](a, b), res) vereq(m(a, b), res) bm = getattr(a, meth) vereq(bm(b), res) @@ -362,8 +362,8 @@ pass # Two essentially featureless objects, just inheriting stuff from - # object. - vereq(dir(None), dir(Ellipsis)) + # object. NB. in PyPy, dir(None) additionally contains '__nonzero__'. + vereq(dir(object()), dir(Ellipsis)) # Nasty test case for proxied objects class Wrapper(object): @@ -1557,7 +1557,7 @@ class E: # *not* subclassing from C foo = C.foo vereq(E().foo, C.foo) # i.e., unbound - verify(repr(C.foo.__get__(C())).startswith("", testfunc.__name__, "FAILURE(%d/%d)" % (success, n), str(e) + else: + success += 1 + print "-->", testfunc.__name__, "OK(%d/%d)" % (success, n) + + if n != success: + raise TestFailed, "%d/%d" % (success, n) + else: + if verbose: print "All OK" if __name__ == "__main__": test_main() From cfbolz at codespeak.net Fri Aug 5 13:41:15 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 5 Aug 2005 13:41:15 +0200 (CEST) Subject: [pypy-svn] r15677 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050805114115.5AC7927B47@code1.codespeak.net> Author: cfbolz Date: Fri Aug 5 13:41:14 2005 New Revision: 15677 Added: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: first attempt converter that converts lltype _ instances into data in memory that the lltypesimulator can use. Added: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Fri Aug 5 13:41:14 2005 @@ -0,0 +1,71 @@ +from pypy.rpython.memory import lladdress +from pypy.rpython.memory.lltypesimulation import simulatorptr, get_total_size +from pypy.rpython.memory.lltypesimulation import get_fixed_size +from pypy.rpython.memory.lltypesimulation import get_variable_size +from pypy.rpython.memory.lltypesimulation import primitive_to_fmt +from pypy.rpython.memory.lltypesimulation import get_layout +from pypy.objspace.flow.model import Constant +from pypy.rpython import lltype + +class LLTypeConverter(object): + def __init__(self, address): + self.curraddress = address + + def convert(self, val_or_ptr, inline_to_addr=None): + print "convert", val_or_ptr, inline_to_addr + TYPE = lltype.typeOf(val_or_ptr) + if isinstance(TYPE, lltype.Primitive): + if inline_to_addr is not None: + inline_to_addr._store(primitive_to_fmt[TYPE], val_or_ptr) + return val_or_ptr + elif isinstance(TYPE, lltype.Array): + return self.convert_array(val_or_ptr, inline_to_addr) + elif isinstance(TYPE, lltype.Struct): + return self.convert_struct(val_or_ptr, inline_to_addr) + elif isinstance(TYPE, lltype.Ptr): + return self.convert_pointer(val_or_ptr, inline_to_addr) + else: + assert 0, "not yet implemented" + + def convert_array(self, _array, inline_to_addr): + print "convert_array", _array, inline_to_addr + TYPE = lltype.typeOf(_array) + arraylength = len(_array.items) + size = get_total_size(TYPE, arraylength) + if inline_to_addr is not None: + startaddr = inline_to_addr + else: + startaddr = self.curraddress + startaddr.signed[0] = arraylength + curraddr = startaddr + get_fixed_size(TYPE) + varsize = get_variable_size(TYPE) + self.curraddress += size + for item in _array.items: + self.convert(item, curraddr) + curraddr += varsize + return startaddr + + def convert_struct(self, _struct, inline_to_addr): + print "convert_struct", _struct, inline_to_addr, + TYPE = lltype.typeOf(_struct) + layout = get_layout(TYPE) + print layout + size = get_total_size(TYPE) + if inline_to_addr is not None: + startaddr = inline_to_addr + else: + startaddr = self.curraddress + self.curraddress += size + for name in TYPE._flds: + addr = startaddr + layout[name] + self.convert(getattr(_struct, name), addr) + return startaddr + + def convert_pointer(self, _ptr, inline_to_addr): + print "convert_pointer", _ptr, inline_to_addr + TYPE = lltype.typeOf(_ptr) + addr = self.convert(_ptr._obj) + assert isinstance(addr, lladdress.Address) + if inline_to_addr is not None: + inline_to_addr.address[0] = addr + return simulatorptr(TYPE, addr) Added: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Fri Aug 5 13:41:14 2005 @@ -0,0 +1,51 @@ +from pypy.rpython.memory.lltypesimulation import * +from pypy.rpython.memory.convertlltype import LLTypeConverter + +def test_convert_primitives(): + cvter = LLTypeConverter(lladdress.NULL) + addr = lladdress.raw_malloc(10) + c1 = cvter.convert(1) + c = cvter.convert("c") + assert c1 == 1 + assert c == "c" + cvter.convert(10, addr) + assert addr.signed[0] == 10 + cvter.convert("c", addr) + assert addr.char[0] == "c" + +def test_convert_array_of_primitives(): + cvter = LLTypeConverter(lladdress.raw_malloc(1000)) + A = lltype.GcArray(lltype.Signed) + lls = lltype.malloc(A, 3) + lls[0] = 1 + lls[1] = 2 + a = cvter.convert(lls) + assert a[0] == 1 + assert a[1] == 2 + +def test_convert_array_of_structs(): + cvter = LLTypeConverter(lladdress.raw_malloc(1000)) + S = lltype.Struct("test", ("v1", lltype.Signed), ("v2", lltype.Signed)) + Ar = lltype.GcArray(S) + llx = lltype.malloc(Ar, 3) + llx[0].v1 = 1 + llx[1].v1 = 2 + llx[2].v1 = 3 + x = cvter.convert(llx) + assert [x[z].v1 for z in range(3)] == [1, 2, 3] + assert [x[z].v2 for z in range(3)] == [0, 0, 0] + +def test_convert_array_of_ptrs(): + cvter = LLTypeConverter(lladdress.raw_malloc(1000)) + S = lltype.GcStruct("name", ("v", lltype.Signed)) + A = lltype.GcArray(lltype.Ptr(S)) + lla = lltype.malloc(A, 3) + lla[0] = lltype.malloc(S) + lla[0].v = 1 + lla[1] = lltype.malloc(S) + lla[1].v = 2 + lla[2] = lltype.malloc(S) + lla[2].v = 2 + x = cvter.convert(lla) + assert [x[z].v for z in range(3)] == [1, 2, 3] + From arigo at codespeak.net Fri Aug 5 13:50:40 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 13:50:40 +0200 (CEST) Subject: [pypy-svn] r15679 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050805115040.A391527B47@code1.codespeak.net> Author: arigo Date: Fri Aug 5 13:50:33 2005 New Revision: 15679 Added: pypy/dist/lib-python/modified-2.4.1/test/test_enumerate.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/test_enumerate.py pypy/dist/lib-python/modified-2.4.1/test/test_exceptions.py - copied, changed from r15656, pypy/dist/lib-python/2.4.1/test/test_exceptions.py pypy/dist/lib-python/modified-2.4.1/test/tf_inherit_check.py - copied unchanged from r15656, pypy/dist/lib-python/2.4.1/test/tf_inherit_check.py Modified: pypy/dist/lib-python/modified-2.4.1/test/seq_tests.py pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py Log: Last round (I think) of ports of modified-2.3.4/test. Modified: pypy/dist/lib-python/modified-2.4.1/test/seq_tests.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/seq_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/seq_tests.py Fri Aug 5 13:50:33 2005 @@ -177,6 +177,7 @@ #def test_getitemoverwriteiter(self): # # Verify that __getitem__ overrides are not recognized by __iter__ + # XXX PyPy behaves differently on this detail # class T(self.type2test): # def __getitem__(self, key): # return str(key) + '!!!' Copied: pypy/dist/lib-python/modified-2.4.1/test/test_enumerate.py (from r15656, pypy/dist/lib-python/2.4.1/test/test_enumerate.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_enumerate.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_enumerate.py Fri Aug 5 13:50:33 2005 @@ -101,7 +101,8 @@ self.assertRaises(TypeError, self.enum, 1) # wrong type (not iterable) self.assertRaises(TypeError, self.enum, 'abc', 2) # too many arguments - def test_tuple_reuse(self): + #Don't test this in PyPy, since the tuple can't be reused + def DONOT_test_tuple_reuse(self): # Tests an implementation detail where tuple is reused # whenever nothing else holds a reference to it self.assertEqual(len(set(map(id, list(enumerate(self.seq))))), len(self.seq)) @@ -119,9 +120,12 @@ seq, res = '', [] class TestBig(EnumerateTestCase): + ##original test (takes too long in PyPy): + #seq = range(10,20000, 2) + #res = zip(range(20000), seq) - seq = range(10,20000,2) - res = zip(range(20000), seq) + seq = range(10, 200, 2) + res = zip(range(200), seq) class TestReversed(unittest.TestCase): Copied: pypy/dist/lib-python/modified-2.4.1/test/test_exceptions.py (from r15656, pypy/dist/lib-python/2.4.1/test/test_exceptions.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_exceptions.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_exceptions.py Fri Aug 5 13:50:33 2005 @@ -29,7 +29,7 @@ def r(thing): test_raise_catch(thing) - if isinstance(thing, ClassType): + if isinstance(thing, (type, ClassType)): print thing.__name__ else: print thing @@ -204,7 +204,11 @@ else: print "Expected exception" -if not sys.platform.startswith('java'): +try: + import _testcapi +except ImportError: + pass +else: test_capi1() test_capi2() Modified: pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_tempfile.py Fri Aug 5 13:50:33 2005 @@ -509,7 +509,7 @@ def tearDown(self): import shutil if self.dir: - shutil.rmtree(self.dir) + shutil.rmtree(self.dir, ignore_errors=True) self.dir = None class mktemped: From pedronis at codespeak.net Fri Aug 5 13:52:44 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 13:52:44 +0200 (CEST) Subject: [pypy-svn] r15681 - pypy/dist/lib-python Message-ID: <20050805115244.7ED2227B47@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 13:52:43 2005 New Revision: 15681 Modified: pypy/dist/lib-python/failure_list.txt Log: update Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 13:52:43 2005 @@ -43,6 +43,6 @@ overriding __repr__ in a dict subclass doesn't change the str(). The dict class should not have an __str__ of its own. -test_sort FIXED? +test_sort FIXED different way of detecting mutations during sort: PyPy didn't detect changes done by the __del__ method of the key-wrapper objects. From arigo at codespeak.net Fri Aug 5 13:56:54 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 13:56:54 +0200 (CEST) Subject: [pypy-svn] r15682 - pypy/dist/lib-python Message-ID: <20050805115654.CA1F727B43@code1.codespeak.net> Author: arigo Date: Fri Aug 5 13:56:52 2005 New Revision: 15682 Modified: pypy/dist/lib-python/failure_list.txt Log: Failing tests that have a better chance now. Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 13:56:52 2005 @@ -46,3 +46,11 @@ test_sort FIXED different way of detecting mutations during sort: PyPy didn't detect changes done by the __del__ method of the key-wrapper objects. + +test_exceptions +test_tempfile +test_cpickle +test_descr +test_str + FIXED? should be re-run. Were fixed in modified-2.3.4, but then they + were somehow lost when we switched to 2.4.1... From pedronis at codespeak.net Fri Aug 5 14:26:11 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 14:26:11 +0200 (CEST) Subject: [pypy-svn] r15684 - pypy/dist/lib-python Message-ID: <20050805122611.024B427B43@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 14:26:11 2005 New Revision: 15684 Modified: pypy/dist/lib-python/failure_list.txt Log: update Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 14:26:11 2005 @@ -47,10 +47,17 @@ different way of detecting mutations during sort: PyPy didn't detect changes done by the __del__ method of the key-wrapper objects. -test_exceptions +test_str + there's some optimisation tests failing + test_tempfile + still failing + +test_exceptions + mismatch in SyntaxError messages + + test_cpickle test_descr -test_str FIXED? should be re-run. Were fixed in modified-2.3.4, but then they were somehow lost when we switched to 2.4.1... From cfbolz at codespeak.net Fri Aug 5 14:45:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 5 Aug 2005 14:45:17 +0200 (CEST) Subject: [pypy-svn] r15685 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050805124517.2EA7727B47@code1.codespeak.net> Author: cfbolz Date: Fri Aug 5 14:45:16 2005 New Revision: 15685 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: oops, bug in _expose. Fix plus test (plus change in repr of simulatorptr, hex address look very memoryly but...). Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Fri Aug 5 14:45:16 2005 @@ -72,7 +72,7 @@ elif isinstance(T, lltype.Primitive): return address._load(primitive_to_fmt[T])[0] elif isinstance(T, lltype.Ptr): - return simulatorptr(T, address) + return simulatorptr(T, address.address[0]) else: assert 0, "not implemented yet" @@ -155,7 +155,7 @@ if T2 != T1: raise TypeError("%r items:\n" "expect %r\n" - " got %r" % (self._T, T1, T2)) + " got %r" % (self._T, T1, T2)) if not (0 <= i < self._address.signed[0]): raise IndexError, "array index out of bounds" if isinstance(T2, lltype.Ptr): @@ -182,10 +182,7 @@ return self._address == other._address def __repr__(self): - addr = self._address.intaddress - if addr < 0: - addr += 256 ** struct.calcsize("P") - return '' % (self._TYPE.TO, addr) + return '' % (self._TYPE.TO, self._address) def cast_pointer(PTRTYPE, ptr): Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Fri Aug 5 14:45:16 2005 @@ -237,6 +237,19 @@ a[2].v = 3 assert [a[z].v for z in range(3)] == [1, 2, 3] +def test_array_of_ptr_to_bigger_struct(): + S = lltype.GcStruct("name", ("v1", lltype.Signed), ("v2", lltype.Signed)) + A = lltype.GcArray(lltype.Ptr(S)) + a = malloc(A, 3) + assert not a[0] + assert not a[1] + a[0] = malloc(S) + a[0].v1 = 1 + a[0].v2 = 2 + assert a[0].v1 == 1 + assert a[0].v2 == 2 + assert not a[1] + def DONOTtest_getRuntimeTypeInfo(): S = GcStruct('s', ('x', Signed)) py.test.raises(ValueError, "getRuntimeTypeInfo(S)") From pedronis at codespeak.net Fri Aug 5 14:57:55 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 14:57:55 +0200 (CEST) Subject: [pypy-svn] r15687 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050805125755.C234E27B47@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 14:57:54 2005 New Revision: 15687 Modified: pypy/dist/lib-python/modified-2.4.1/test/string_tests.py Log: disable tests form impl specific optimisations Modified: pypy/dist/lib-python/modified-2.4.1/test/string_tests.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/string_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/string_tests.py Fri Aug 5 14:57:54 2005 @@ -749,9 +749,11 @@ self.assert_(s1 is not s2) self.assert_(type(s2) is t) - s1 = t("abcd") - s2 = t().join([s1]) - self.assert_(s1 is s2) + + # XXX impl. specific optimisation + #s1 = t("abcd") + #s2 = t().join([s1]) + #self.assert_(s1 is s2) # Should also test mixed-type join. if t is unicode: @@ -760,9 +762,10 @@ self.assert_(s1 is not s2) self.assert_(type(s2) is t) - s1 = t("abcd") - s2 = "".join([s1]) - self.assert_(s1 is s2) + # XXX impl. specific opt. + #s1 = t("abcd") + #s2 = "".join([s1]) + #self.assert_(s1 is s2) elif t is str: s1 = subclass("abcd") From pedronis at codespeak.net Fri Aug 5 15:00:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 15:00:28 +0200 (CEST) Subject: [pypy-svn] r15689 - pypy/dist/lib-python Message-ID: <20050805130028.DDFEF27B47@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 15:00:27 2005 New Revision: 15689 Modified: pypy/dist/lib-python/failure_list.txt Log: update Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 15:00:27 2005 @@ -47,8 +47,8 @@ different way of detecting mutations during sort: PyPy didn't detect changes done by the __del__ method of the key-wrapper objects. -test_str - there's some optimisation tests failing +test_str FIXED + there's some optimisation tests failing => disabled them test_tempfile still failing From cfbolz at codespeak.net Fri Aug 5 15:07:21 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 5 Aug 2005 15:07:21 +0200 (CEST) Subject: [pypy-svn] r15691 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050805130721.83BE727B42@code1.codespeak.net> Author: cfbolz Date: Fri Aug 5 15:07:20 2005 New Revision: 15691 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: fixed problems with circular data structures + tests Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Fri Aug 5 15:07:20 2005 @@ -9,10 +9,10 @@ class LLTypeConverter(object): def __init__(self, address): + self.converted = {} self.curraddress = address def convert(self, val_or_ptr, inline_to_addr=None): - print "convert", val_or_ptr, inline_to_addr TYPE = lltype.typeOf(val_or_ptr) if isinstance(TYPE, lltype.Primitive): if inline_to_addr is not None: @@ -28,7 +28,10 @@ assert 0, "not yet implemented" def convert_array(self, _array, inline_to_addr): - print "convert_array", _array, inline_to_addr + if _array in self.converted: + address = self.converted[_array] + assert inline_to_addr is None or address == inline_to_addr + return address TYPE = lltype.typeOf(_array) arraylength = len(_array.items) size = get_total_size(TYPE, arraylength) @@ -36,6 +39,7 @@ startaddr = inline_to_addr else: startaddr = self.curraddress + self.converted[_array] = startaddr startaddr.signed[0] = arraylength curraddr = startaddr + get_fixed_size(TYPE) varsize = get_variable_size(TYPE) @@ -46,15 +50,18 @@ return startaddr def convert_struct(self, _struct, inline_to_addr): - print "convert_struct", _struct, inline_to_addr, + if _struct in self.converted: + address = self.converted[_struct] + assert inline_to_addr is None or address == inline_to_addr + return address TYPE = lltype.typeOf(_struct) layout = get_layout(TYPE) - print layout size = get_total_size(TYPE) if inline_to_addr is not None: startaddr = inline_to_addr else: startaddr = self.curraddress + self.converted[_struct] = startaddr self.curraddress += size for name in TYPE._flds: addr = startaddr + layout[name] @@ -62,7 +69,6 @@ return startaddr def convert_pointer(self, _ptr, inline_to_addr): - print "convert_pointer", _ptr, inline_to_addr TYPE = lltype.typeOf(_ptr) addr = self.convert(_ptr._obj) assert isinstance(addr, lladdress.Address) Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Fri Aug 5 15:07:20 2005 @@ -45,7 +45,47 @@ lla[1] = lltype.malloc(S) lla[1].v = 2 lla[2] = lltype.malloc(S) - lla[2].v = 2 + lla[2].v = 3 + assert [lla[z].v for z in range(3)] == [1, 2, 3] + print lla + print [lla[z] for z in range(3)] x = cvter.convert(lla) + print x + print [x[z] for z in range(3)] + print x._address._load("iiiiiii") assert [x[z].v for z in range(3)] == [1, 2, 3] + +def test_circular_struct(): + cvter = LLTypeConverter(lladdress.raw_malloc(100)) + F = lltype.GcForwardReference() + S = lltype.GcStruct('abc', ('x', lltype.Ptr(F))) + F.become(S) + lls = lltype.malloc(S) + lls.x = lls + s = cvter.convert(lls) + assert s.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x == s + +def test_circular_array(): + cvter = LLTypeConverter(lladdress.raw_malloc(1000)) + F = lltype.GcForwardReference() + A = lltype.GcArray(lltype.Ptr(F)) + S = lltype.GcStruct("name", ("a", lltype.Ptr(A)), ("b", lltype.Signed)) + F.become(S) + lla = lltype.malloc(A, 3) + lla[0] = lltype.malloc(S) + lla[1] = lltype.malloc(S) + lla[2] = lltype.malloc(S) + lla[0].a = lla + lla[1].a = lla + lla[2].a = lla + lla[0].b = 1 + lla[1].b = 2 + lla[2].b = 3 + assert lla[0].a[1].a[2].a == lla + assert [lla[i].b for i in range(3)] == [1, 2, 3] + a = cvter.convert(lla) + assert a[0].a[1].a[2].a == a + assert [a[i].b for i in range(3)] == [1, 2, 3] + + From cfbolz at codespeak.net Fri Aug 5 16:39:29 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 5 Aug 2005 16:39:29 +0200 (CEST) Subject: [pypy-svn] r15694 - pypy/dist/pypy/rpython Message-ID: <20050805143929.A3AB327B45@code1.codespeak.net> Author: cfbolz Date: Fri Aug 5 16:39:29 2005 New Revision: 15694 Removed: pypy/dist/pypy/rpython/chooselltype.py Modified: pypy/dist/pypy/rpython/llinterp.py Log: as to samuele's suggestion, added an argument to llinterpreter constructor, the lltype implementation. this will make it possible to change it without using a flaky global var in some module. Deleted: /pypy/dist/pypy/rpython/chooselltype.py ============================================================================== --- /pypy/dist/pypy/rpython/chooselltype.py Fri Aug 5 16:39:29 2005 +++ (empty file) @@ -1,24 +0,0 @@ -# XXX this whole thing is messy. - -# choose the lltype implementation with the following variable: -# 0 is the original pypy/rpython/lltype.py -# 1 is the lltype implementation on top of the memory simulator: -# pypy/rpython/memory/lltypesimulation.py - -use_lltype_number = 0 - -def raising(*args): - raise NotImplemented, "missing function" - -if use_lltype_number == 0: - from pypy.rpython.lltype import _ptr, Ptr, Void, typeOf, malloc, cast_pointer, PyObject, pyobjectptr - from pypy.rpython.lltype import Array, Struct - from pypy.rpython.rmodel import getfunctionptr -elif use_lltype_number == 1: - from pypy.rpython.lltype import Ptr, Void, typeOf, PyObject - from pypy.rpython.lltype import Array, Struct - from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr, cast_pointer, malloc - pyobjectptr = raising - getfunctionptr = raising -else: - raise ValueError, "unknown lltype number" Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Aug 5 16:39:29 2005 @@ -2,11 +2,11 @@ from pypy.tool.sourcetools import compile2 from pypy.objspace.flow.model import Constant, Variable, last_exception from pypy.rpython.rarithmetic import intmask, r_uint, ovfcheck -import py -from pypy.rpython.chooselltype import _ptr, Ptr, Void, typeOf, malloc, cast_pointer, PyObject, pyobjectptr -from pypy.rpython.chooselltype import Array, Struct -from pypy.rpython.chooselltype import getfunctionptr +from pypy.rpython import lltype +from pypy.rpython.rmodel import getfunctionptr + import math +import py log = py.log.Producer('llinterp') @@ -16,10 +16,11 @@ class LLInterpreter(object): """ low level interpreter working with concrete values. """ - def __init__(self, flowgraphs, typer): + def __init__(self, flowgraphs, typer, lltype=lltype): self.flowgraphs = flowgraphs self.bindings = {} self.typer = typer + self.llt = lltype #module that contains the used lltype classes self.active_frame = None def getgraph(self, func): @@ -67,6 +68,7 @@ self.graph = graph self.args = args self.llinterpreter = llinterpreter + self.llt = llinterpreter.llt self.bindings = {} self.f_back = f_back self.curr_block = None @@ -84,8 +86,8 @@ self.setvar(var, val) def setvar(self, var, val): - if var.concretetype != Void: - assert var.concretetype == typeOf(val) + if var.concretetype != self.llt.Void: + assert var.concretetype == self.llt.typeOf(val) assert isinstance(var, Variable) self.bindings[var] = val @@ -194,7 +196,7 @@ assert False, "op_direct_call above should have raised" else: exc_class = exc.__class__ - evalue = exdata.ll_pyexcclass2exc(pyobjectptr(exc_class)) + evalue = exdata.ll_pyexcclass2exc(self.llt.pyobjectptr(exc_class)) etype = exdata.ll_type_of_exc_inst(evalue) raise LLException(etype, evalue) @@ -213,8 +215,8 @@ def op_setfield(self, obj, fieldname, fieldvalue): # obj should be pointer - FIELDTYPE = getattr(typeOf(obj).TO, fieldname) - if FIELDTYPE != Void: + FIELDTYPE = getattr(self.llt.typeOf(obj).TO, fieldname) + if FIELDTYPE != self.llt.Void: setattr(obj, fieldname, fieldvalue) def op_getarrayitem(self, array, index): @@ -222,8 +224,8 @@ def op_setarrayitem(self, array, index, item): # array should be a pointer - ITEMTYPE = typeOf(array).TO.OF - if ITEMTYPE != Void: + ITEMTYPE = self.llt.typeOf(array).TO.OF + if ITEMTYPE != self.llt.Void: array[index] = item def op_direct_call(self, f, *args): @@ -242,29 +244,31 @@ return frame.eval() def op_malloc(self, obj): - return malloc(obj) + return self.llt.malloc(obj) def op_getfield(self, obj, field): - assert isinstance(obj, _ptr) + assert isinstance(obj, self.llt._ptr) result = getattr(obj, field) # check the difference between op_getfield and op_getsubstruct: # the former returns the real field, the latter a pointer to it - assert typeOf(result) == getattr(typeOf(obj).TO, field) + assert self.llt.typeOf(result) == getattr(self.llt.typeOf(obj).TO, + field) return result def op_getsubstruct(self, obj, field): - assert isinstance(obj, _ptr) + assert isinstance(obj, self.llt._ptr) result = getattr(obj, field) # check the difference between op_getfield and op_getsubstruct: # the former returns the real field, the latter a pointer to it - assert typeOf(result) == Ptr(getattr(typeOf(obj).TO, field)) + assert (self.llt.typeOf(result) == + self.llt.Ptr(getattr(self.llt.typeOf(obj).TO, field))) return result def op_malloc_varsize(self, obj, size): - return malloc(obj, size) + return self.llt.malloc(obj, size) def op_getarraysubstruct(self, array, index): - assert isinstance(array, _ptr) + assert isinstance(array, self.llt._ptr) result = array[index] return result # the diff between op_getarrayitem and op_getarraysubstruct @@ -272,34 +276,35 @@ def op_getarraysize(self, array): #print array,type(array),dir(array) - assert isinstance(typeOf(array).TO, Array) + assert isinstance(self.llt.typeOf(array).TO, self.llt.Array) return len(array) def op_cast_pointer(self, tp, obj): # well, actually this is what's now in the globals. - return cast_pointer(tp, obj) + return self.llt.cast_pointer(tp, obj) def op_ptr_eq(self, ptr1, ptr2): - assert isinstance(ptr1, _ptr) - assert isinstance(ptr2, _ptr) + assert isinstance(ptr1, self.llt._ptr) + assert isinstance(ptr2, self.llt._ptr) return ptr1 == ptr2 def op_ptr_ne(self, ptr1, ptr2): - assert isinstance(ptr1, _ptr) - assert isinstance(ptr2, _ptr) + assert isinstance(ptr1, self.llt._ptr) + assert isinstance(ptr2, self.llt._ptr) return ptr1 != ptr2 def op_ptr_nonzero(self, ptr1): - assert isinstance(ptr1, _ptr) + assert isinstance(ptr1, self.llt._ptr) return bool(ptr1) def op_ptr_iszero(self, ptr1): - assert isinstance(ptr1, _ptr) + assert isinstance(ptr1, self.llt._ptr) return not bool(ptr1) def op_cast_ptr_to_int(self, ptr1): # xxx should this logic migrate to lltype _ptr itself? - assert isinstance(ptr1, _ptr) - assert isinstance(typeOf(ptr1).TO, (Array, Struct)) + assert isinstance(ptr1, self.llt._ptr) + assert isinstance(self.llt.typeOf(ptr1).TO, (self.llt.Array, + self.llt.Struct)) obj = ptr1._obj while obj._parentstructure(): obj = obj._parentstructure() @@ -377,22 +382,22 @@ exec py.code.Source(""" def op_%(opname)s(self, *pyobjs): for pyo in pyobjs: - assert typeOf(pyo) == Ptr(PyObject) + assert self.llt.typeOf(pyo) == self.llt.Ptr(self.llt.PyObject) func = opimpls[%(opname)r] try: pyo = func(*[pyo._obj.value for pyo in pyobjs]) except Exception, e: self.make_llexception(e) - return pyobjectptr(pyo) + return self.llt.pyobjectptr(pyo) """ % locals()).compile() del opname def op_simple_call(self, f, *args): - assert typeOf(f) == Ptr(PyObject) + assert self.llt.typeOf(f) == self.llt.Ptr(self.llt.PyObject) for pyo in args: - assert typeOf(pyo) == Ptr(PyObject) + assert self.llt.typeOf(pyo) == self.llt.Ptr(self.llt.PyObject) res = f._obj.value(*[pyo._obj.value for pyo in args]) - return pyobjectptr(res) + return self.llt.pyobjectptr(res) # __________________________________________________________ # primitive operations From arigo at codespeak.net Fri Aug 5 17:10:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 17:10:27 +0200 (CEST) Subject: [pypy-svn] r15696 - pypy/dist/pypy/translator/tool Message-ID: <20050805151027.10CFC27B45@code1.codespeak.net> Author: arigo Date: Fri Aug 5 17:10:25 2005 New Revision: 15696 Added: pypy/dist/pypy/translator/tool/reftracker.py (contents, props changed) Log: A useful tool: a general-purpose reference tracker, to look for why objects are unexpectedly kept alive in Python programs. (dot+pygame tool) Added: pypy/dist/pypy/translator/tool/reftracker.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/tool/reftracker.py Fri Aug 5 17:10:25 2005 @@ -0,0 +1,105 @@ +""" +General-purpose reference tracker. +Usage: call track(obj). +""" + +import autopath +import gc +from pypy.translator.tool.graphpage import GraphPage, DotGen + + +MARKER = object() + + +class RefTrackerPage(GraphPage): + + def compute(self, objectlist): + assert objectlist[0] is MARKER + self.objectlist = objectlist + dotgen = DotGen('reftracker') + id2typename = {} + nodes = {} + edges = {} + + def addedge(o1, o2): + key = (id(o1), id(o2)) + slst = [] + if type(o1) in (list, tuple): + for i in range(len(o1)): + if o1[i] is o2: + slst.append('[%d]' % i) + elif type(o1) is dict: + for k, v in o1.items(): + if v is o2: + slst.append('[%r]' % (k,)) + edges[key] = ', '.join(slst) + + for i in range(1, len(objectlist)): + s = repr(objectlist[i]) + word = '0x%x' % id(objectlist[i]) + if len(s) > 50: + self.links[word] = s + s = s[:20] + ' ... ' + s[-20:] + s = '<%s> %s\\n%s' % (type(objectlist[i]).__name__, + word, + s) + nodename = 'node%d' % len(nodes) + dotgen.emit_node(nodename, label=s, shape="box") + nodes[id(objectlist[i])] = nodename + for o2 in gc.get_referents(objectlist[i]): + if o2 is None: + continue + addedge(objectlist[i], o2) + id2typename[id(o2)] = type(o2).__name__ + del o2 + for o2 in gc.get_referrers(objectlist[i]): + if o2 is None: + continue + if type(o2) is list and o2 and o2[0] is MARKER: + continue + addedge(o2, objectlist[i]) + id2typename[id(o2)] = type(o2).__name__ + del o2 + + for ids, label in edges.items(): + for id1 in ids: + if id1 not in nodes: + nodename = 'node%d' % len(nodes) + word = '0x%x' % id1 + s = '<%s> %s' % (id2typename[id1], word) + dotgen.emit_node(nodename, label=s) + nodes[id1] = nodename + self.links[word] = s + id1, id2 = ids + dotgen.emit_edge(nodes[id1], nodes[id2], label=label) + + self.source = dotgen.generate(target=None) + + def followlink(self, word): + id1 = int(word, 16) + found = None + objectlist = self.objectlist + for i in range(1, len(objectlist)): + for o2 in gc.get_referents(objectlist[i]): + if id(o2) == id1: + found = o2 + for o2 in gc.get_referrers(objectlist[i]): + if id(o2) == id1: + found = o2 + if found is not None: + objectlist = objectlist + [found] + else: + print '*** NOTE: object not found' + return RefTrackerPage(objectlist) + + +def track(o): + """Invoke a dot+pygame object reference tracker.""" + page = RefTrackerPage([MARKER, o]) + del o + page.display() + + +if __name__ == '__main__': + d = {"lskjadldjslkj": "adjoiadoixmdoiemdwoi"} + track(d) From hpk at codespeak.net Fri Aug 5 17:16:44 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 5 Aug 2005 17:16:44 +0200 (CEST) Subject: [pypy-svn] r15697 - pypy/dist/pypy/tool/pytest Message-ID: <20050805151644.5E64D27B45@code1.codespeak.net> Author: hpk Date: Fri Aug 5 17:16:43 2005 New Revision: 15697 Modified: pypy/dist/pypy/tool/pytest/result.py Log: a bit more care with cpuinfo as asked for by xorAxAx Modified: pypy/dist/pypy/tool/pytest/result.py ============================================================================== --- pypy/dist/pypy/tool/pytest/result.py (original) +++ pypy/dist/pypy/tool/pytest/result.py Fri Aug 5 17:16:43 2005 @@ -140,8 +140,8 @@ result['python-version-info'] = sys.version_info info = try_getcpuinfo() if info is not None: - result['cpu model'] = info['model name'] - result['cpu mhz'] = info['cpu mhz'] + result['cpu model'] = info.get('model name', "unknown") + result['cpu mhz'] = info.get('cpu mhz', 'unknown') # # # From arigo at codespeak.net Fri Aug 5 17:23:34 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 5 Aug 2005 17:23:34 +0200 (CEST) Subject: [pypy-svn] r15698 - in pypy/dist/pypy: interpreter objspace/std/test Message-ID: <20050805152334.8E93C27B45@code1.codespeak.net> Author: arigo Date: Fri Aug 5 17:23:30 2005 New Revision: 15698 Modified: pypy/dist/pypy/interpreter/error.py pypy/dist/pypy/interpreter/typedef.py pypy/dist/pypy/objspace/std/test/test_userobject.py Log: More support for __del__() methods. This one catches and prints an error message. This was more delicate than expected because of GC cycles that kept the 'self' object alive just a bit longer than the __del__() execution. This systematically triggers another call to __del__() when the GC breaks the cycle... Added a test. Modified: pypy/dist/pypy/interpreter/error.py ============================================================================== --- pypy/dist/pypy/interpreter/error.py (original) +++ pypy/dist/pypy/interpreter/error.py Fri Aug 5 17:23:30 2005 @@ -37,19 +37,20 @@ return '[%s: %s]' % (self.w_type, self.w_value) def errorstr(self, space): - "NOT_RPYTHON: The exception class and value, as a string." + "The exception class and value, as a string." if space is None: + # this part NOT_RPYTHON exc_typename = str(self.w_type) - exc_value = self.w_value + exc_value = str(self.w_value) else: w = space.wrap - if space.is_true(space.is_(space.type(self.w_type), space.w_str)): + if space.is_w(space.type(self.w_type), space.w_str): exc_typename = space.str_w(self.w_type) else: exc_typename = space.str_w( space.getattr(self.w_type, w('__name__'))) - if self.w_value == space.w_None: - exc_value = None + if space.is_w(self.w_value, space.w_None): + exc_value = "" else: try: exc_value = space.str_w(space.str(self.w_value)) @@ -193,6 +194,21 @@ self.w_type = w_type self.w_value = w_value + def write_unraisable(self, space, where, w_object=None): + if w_object is None: + objrepr = '' + else: + try: + objrepr = space.str_w(space.repr(w_object)) + except OperationError: + objrepr = '?' + msg = 'Exception "%s" in %s%s ignored\n' % (self.errorstr(space), + where, objrepr) + try: + space.call_method(space.sys.get('stderr'), 'write', space.wrap(msg)) + except OperationError: + pass # ignored + # Utilities from pypy.tool.ansi_print import ansi_print Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Fri Aug 5 17:23:30 2005 @@ -86,7 +86,11 @@ self.w__class__ = w_subtype def __del__(self): - self.space.userdel(self) + try: + self.space.userdel(self) + except OperationError, e: + e.write_unraisable(self.space, 'method __del__ of ', self) + e.clear(self.space) # break up reference cycles if wants_slots: def user_setup_slots(self, nslots): Modified: pypy/dist/pypy/objspace/std/test/test_userobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_userobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_userobject.py Fri Aug 5 17:23:30 2005 @@ -141,3 +141,37 @@ a.__dict__ = {'y': 6} assert a.y == 6 assert not hasattr(a, 'x') + + def test_del(self): + lst = [] + class A(object): + def __del__(self): + lst.append(42) + A() + assert lst == [42] + + def test_del_exception(self): + import sys, StringIO + class A(object): + def __del__(self): + yaddadlaouti + prev = sys.stderr + try: + sys.stderr = StringIO.StringIO() + A() + res = sys.stderr.getvalue() + A() + res2 = sys.stderr.getvalue() + finally: + sys.stderr = prev + assert res.startswith('Exception') + assert 'NameError' in res + assert 'yaddadlaouti' in res + assert 'ignored' in res + assert res.count('\n') == 1 # a single line + assert res2.count('\n') == 2 # two lines + line2 = res2.split('\n')[1] + assert line2.startswith('Exception') + assert 'NameError' in line2 + assert 'yaddadlaouti' in line2 + assert 'ignored' in line2 From pedronis at codespeak.net Fri Aug 5 17:49:41 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 17:49:41 +0200 (CEST) Subject: [pypy-svn] r15700 - pypy/dist/lib-python Message-ID: <20050805154941.0043E27B45@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 17:49:40 2005 New Revision: 15700 Modified: pypy/dist/lib-python/failure_list.txt Log: update Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 5 17:49:40 2005 @@ -28,6 +28,11 @@ - __future__ import division problems +test_mutants + still crashes because it does a str() on a a mutating dict + which results in a RuntimeError, what does CPython output in this case? + + test_tuple etc do we want to support x is x*1 where x is exactly a tuple? @@ -39,9 +44,6 @@ test_optparse FIXED -test_mutants FIXED? - overriding __repr__ in a dict subclass doesn't change the str(). - The dict class should not have an __str__ of its own. test_sort FIXED different way of detecting mutations during sort: PyPy didn't detect From ericvrp at codespeak.net Fri Aug 5 17:51:31 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 5 Aug 2005 17:51:31 +0200 (CEST) Subject: [pypy-svn] r15701 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050805155131.D967C27B45@code1.codespeak.net> Author: ericvrp Date: Fri Aug 5 17:51:30 2005 New Revision: 15701 Modified: pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_exception.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: - fixed bug that only direct_calls could raise exceptions, operations can now also - added int_floordiv_zer and uint_floordiv_zer - cleaned up similar attempt in genllvm.py Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Fri Aug 5 17:51:30 2005 @@ -156,30 +156,28 @@ codewriter.br(cond, self.block_to_name[block.exits[0].target], self.block_to_name[block.exits[1].target]) - def _last_operation(self, block, opname): - last_index = None - for op_index, op in enumerate(block.operations): - if op.opname == opname: - last_index = op_index - return last_index - def write_block_operations(self, codewriter, block): opwriter = OpWriter(self.db, codewriter, self, block) - last_direct_call_index = self._last_operation(block, 'direct_call') + if block.exitswitch == Constant(last_exception): + last_op_index = len(block.operations) - 1 + else: + last_op_index = None for op_index, op in enumerate(block.operations): - - # print out debug string - codewriter.newline() - codewriter.comment("** %s **" % str(op)) - info = self.db.get_op2comment(op) - if info is not None: - lenofopstr, opstrname = info - codewriter.debugcomment(self.db.repr_tmpvar(), - lenofopstr, - opstrname) - - if op_index == last_direct_call_index and block.exitswitch == Constant(last_exception): - op.opname = 'direct_invoke' + if False: # print out debug string + codewriter.newline() + codewriter.comment("** %s **" % str(op)) + info = self.db.get_op2comment(op) + if info is not None: + lenofopstr, opstrname = info + codewriter.debugcomment(self.db.repr_tmpvar(), + lenofopstr, + opstrname) + if op_index == last_op_index: + #could raise an exception and should therefor have a function + #implementation that can be invoked by the llvm-code. + invoke_prefix = 'invoke:' + assert not op.opname.startswith(invoke_prefix) + op.opname = invoke_prefix + op.opname opwriter.write_operation(op) def write_startblock(self, codewriter, block): Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Fri Aug 5 17:51:30 2005 @@ -20,18 +20,6 @@ function_count = {} -# XXX Temp -raise_impl = """ -ccc void %RaiseSimpleException(int %t, sbyte* %ptErr) { -entry: - unwind - ret void -} -""" - -# XXX Temp -raise_decl = "declare ccc void %RaiseSimpleException(int, sbyte*)" - class GenLLVM(object): def __init__(self, translator, debug=False, embedexterns=True): @@ -89,7 +77,6 @@ nl(); comment("Function Prototypes") ; nl() if self.embedexterns: - codewriter.append(raise_decl) for extdecl in extdeclarations.split('\n'): codewriter.append(extdecl) @@ -125,9 +112,6 @@ codewriter.append(extfunc) depdone[dep] = True - if self.embedexterns: - codewriter.append(raise_impl) - #XXX use codewriter methods here decl = self.entrynode.getdecl() t = decl.split('%', 1) Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 5 17:51:30 2005 @@ -23,3 +23,54 @@ } """) + +extfunctions["%__prepare_ZeroDivisionError"] = ((), """ +fastcc void %__prepare_ZeroDivisionError() { + + %exception_value = call fastcc %structtype.object* %instantiate_ZeroDivisionError() + + %tmp = getelementptr %structtype.object* %exception_value, int 0, uint 0 + %exception_type = load %structtype.object_vtable** %tmp + store %structtype.object_vtable* %exception_type, %structtype.object_vtable** %last_exception_type + store %structtype.object* %exception_value, %structtype.object** %last_exception_value + + ret void +} + +""") + +extfunctions["%int_floordiv_zer"] = (("%__prepare_ZeroDivisionError",), """ +fastcc int %int_floordiv_zer(int %x, int %y) { + %cond = seteq int %y, 0 + br bool %cond, label %is_0, label %is_not_0 +is_not_0: + %z = add int %x, %y + ret int %z +is_0: + call fastcc void %__prepare_ZeroDivisionError() + unwind +} + +""") + +#XXX could use template here +extfunctions["%uint_floordiv_zer"] = (("%__prepare_ZeroDivisionError",), """ +fastcc uint %uint_floordiv_zer(uint %x, uint %y) { + %cond = seteq uint %y, 0 + br bool %cond, label %is_0, label %is_not_0 +is_not_0: + %z = add uint %x, %y + ret uint %z +is_0: + call fastcc void %__prepare_ZeroDivisionError() + unwind +} + +""") + +#src/int.h:#define OP_INT_FLOORDIV_ZER(x,y,r,err) \ done +#src/int.h:#define OP_UINT_FLOORDIV_ZER(x,y,r,err) \ done +#src/int.h:#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \ +#src/int.h:#define OP_INT_MOD_ZER(x,y,r,err) \ +#src/int.h:#define OP_UINT_MOD_ZER(x,y,r,err) \ +#src/int.h:#define OP_INT_MOD_OVF_ZER(x,y,r,err) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Fri Aug 5 17:51:30 2005 @@ -1,6 +1,8 @@ import py from pypy.objspace.flow.model import Constant from pypy.rpython import lltype +from pypy.translator.llvm2.module.extfunction import extfunctions +from pypy.translator.llvm2.extfuncnode import ExternalFuncNode from pypy.translator.llvm2.log import log log = log.opwriter @@ -79,14 +81,18 @@ self.block = block def write_operation(self, op): - if op.opname in self.binary_operations: - self.binaryop(op) - elif op.opname in self.shift_operations: - self.shiftop(op) + invoke = op.opname.startswith('invoke:') + if invoke: + self.invoke(op) else: - meth = getattr(self, op.opname, None) - assert meth is not None, "operation %r not found" %(op.opname,) - meth(op) + if op.opname in self.binary_operations: + self.binaryop(op) + elif op.opname in self.shift_operations: + self.shiftop(op) + else: + meth = getattr(self, op.opname, None) + assert meth is not None, "operation %s not found" %(op.opname,) + meth(op) def _generic_pow(self, op, onestr): mult_type = self.db.repr_arg_type(op.args[0]) @@ -228,11 +234,21 @@ else: self.codewriter.call_void(functionref, argrefs, argtypes) - def direct_invoke(self, op): + def invoke(self, op): # XXX hack as per remove_voids() op_args = [arg for arg in op.args if arg.concretetype is not lltype.Void] + if op.opname == 'invoke:direct_call': + functionref = self.db.repr_arg(op_args[0]) + else: #operation + opname = op.opname.split(':',1)[1] + op_args = ['%' + opname] + op_args + functionref = op_args[0] + ExternalFuncNode.used_external_functions[functionref] = True + assert functionref in extfunctions, \ + "exception raising operation %(opname)s has no implementation" % locals() + assert len(op_args) >= 1 assert len(self.block.exits) >= 2 #at least one label and one exception label @@ -241,7 +257,6 @@ targetvar = self.db.repr_arg(op.result) returntype = self.db.repr_arg_type(op.result) - functionref = self.db.repr_arg(op_args[0]) argrefs = self.db.repr_arg_multi(op_args[1:]) argtypes = self.db.repr_arg_type_multi(op_args[1:]) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Fri Aug 5 17:51:30 2005 @@ -2,6 +2,7 @@ from pypy.translator.llvm2.genllvm import compile_function from pypy.translator.test.snippet import try_raise_choose +from pypy.rpython.rarithmetic import r_uint class TestException(Exception): pass @@ -91,17 +92,28 @@ assert f( 0) == fn( 0) assert f(10) == fn(10) -#def test_divzero(): -# py.test.skip("divzero not working yet") -# def fn(n): -# try: -# n/0 -# except: -# return 2 -# return 4 -# f = compile_function(fn, [int]) -# assert f(0) == fn(0) - +def test_zerodiv_int(): + def zerodiv_int(n): + try: + 100/n + except ZeroDivisionError: + return n+7 + return n+4 + f = compile_function(zerodiv_int, [int]) + assert f(1) == zerodiv_int(1) + assert f(0) == zerodiv_int(0) + +def test_zerodiv_uint(): + def zerodiv_uint(n): + try: + 100/n + except ZeroDivisionError: + return n+7 + return n+4 + f = compile_function(zerodiv_uint, [r_uint]) + assert f(1) == zerodiv_uint(1) + assert f(0) == zerodiv_uint(0) + def test_reraise1(): def fn(n): lst = range(10) Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Fri Aug 5 17:51:30 2005 @@ -211,7 +211,7 @@ # floats def test_float_operations(): - py.test.skip("llvm rem operation doesnt seem to work...fixed in llvm cvs") + #llvm rem operation working starting llvm1.6") #see: http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=611 def func(x, y): z = x + y / 2.1 * x From pedronis at codespeak.net Fri Aug 5 18:46:34 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 18:46:34 +0200 (CEST) Subject: [pypy-svn] r15703 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050805164634.88F7327B45@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 18:46:32 2005 New Revision: 15703 Modified: pypy/dist/pypy/objspace/std/dicttype.py pypy/dist/pypy/objspace/std/test/test_dictobject.py Log: dict.update now accepts iterables or no arguments at all Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Fri Aug 5 18:46:32 2005 @@ -11,7 +11,7 @@ dict_pop = MultiMethod('pop', 2, w_varargs=True) dict_popitem = MultiMethod('popitem', 1) dict_setdefault = MultiMethod('setdefault', 3, defaults=(None,)) -dict_update = MultiMethod('update', 2) +dict_update = MultiMethod('update', 2, defaults=((),)) dict_iteritems = MultiMethod('iteritems', 1) dict_iterkeys = MultiMethod('iterkeys', 1) dict_itervalues = MultiMethod('itervalues', 1) @@ -24,8 +24,12 @@ app = gateway.applevel(''' def update(d, o): - for k in o.keys(): - d[k] = o[k] + if hasattr(o, 'keys'): + for k in o.keys(): + d[k] = o[k] + else: + for k,v in o: + d[k] = v def popitem(d): k = d.keys() Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictobject.py Fri Aug 5 18:46:32 2005 @@ -223,6 +223,18 @@ assert d == dd d.update({3:5, 6:7}) assert d == {1:2, 3:5, 6:7} + + def test_update_iterable(self): + d = {} + d.update((('a',1),)) + assert d == {'a': 1} + d.update([('a',2), ('c',3)]) + assert d == {'a': 2, 'c': 3} + + def test_update_nop(self): + d = {} + d.update() + assert d == {} def test_values(self): d = {1:2, 3:4} From pedronis at codespeak.net Fri Aug 5 18:47:35 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 5 Aug 2005 18:47:35 +0200 (CEST) Subject: [pypy-svn] r15704 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050805164735.DB74F27B45@code1.codespeak.net> Author: pedronis Date: Fri Aug 5 18:47:32 2005 New Revision: 15704 Added: pypy/dist/lib-python/modified-2.4.1/test/mapping_tests.py - copied, changed from r15683, pypy/dist/lib-python/2.4.1/test/mapping_tests.py pypy/dist/lib-python/modified-2.4.1/test/test_dict.py - copied, changed from r15683, pypy/dist/lib-python/2.4.1/test/test_dict.py Log: set iterations number to more approachable values Copied: pypy/dist/lib-python/modified-2.4.1/test/mapping_tests.py (from r15683, pypy/dist/lib-python/2.4.1/test/mapping_tests.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/mapping_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/mapping_tests.py Fri Aug 5 18:47:32 2005 @@ -510,7 +510,7 @@ for copymode in -1, +1: # -1: b has same structure as a # +1: b is a.copy() - for log2size in range(12): + for log2size in range(4): # XXX 12 too large for PyPy size = 2**log2size a = self._empty_mapping() b = self._empty_mapping() Copied: pypy/dist/lib-python/modified-2.4.1/test/test_dict.py (from r15683, pypy/dist/lib-python/2.4.1/test/test_dict.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_dict.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_dict.py Fri Aug 5 18:47:32 2005 @@ -285,7 +285,7 @@ for copymode in -1, +1: # -1: b has same structure as a # +1: b is a.copy() - for log2size in range(12): + for log2size in range(4): # XXX 12 too large for PyPy size = 2**log2size a = {} b = {} From tismer at codespeak.net Fri Aug 5 19:23:05 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 5 Aug 2005 19:23:05 +0200 (CEST) Subject: [pypy-svn] r15706 - pypy/dist/pypy/translator Message-ID: <20050805172305.72A2927B45@code1.codespeak.net> Author: tismer Date: Fri Aug 5 19:23:04 2005 New Revision: 15706 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: removed tabs which cr(e|a)pped in Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Fri Aug 5 19:23:04 2005 @@ -162,7 +162,7 @@ self.rpynames = {Constant(None).key: 'space.w_None', Constant(False).key: 'space.w_False', Constant(True).key: 'space.w_True', - Constant(Ellipsis).key: 'space.w_Ellipsis', + Constant(Ellipsis).key: 'space.w_Ellipsis', Constant(OperationError).key: late_OperationError, Constant(Arguments).key: late_Arguments, } From tismer at codespeak.net Fri Aug 5 20:06:03 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 5 Aug 2005 20:06:03 +0200 (CEST) Subject: [pypy-svn] r15707 - pypy/dist/pypy/rpython Message-ID: <20050805180603.836BF27B47@code1.codespeak.net> Author: tismer Date: Fri Aug 5 20:06:02 2005 New Revision: 15707 Modified: pypy/dist/pypy/rpython/rstr.py Log: de-tabbified Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Fri Aug 5 20:06:02 2005 @@ -157,14 +157,14 @@ return hop.gendirectcall(ll_replace_chr_chr, v_str, v_c1, v_c2) def rtype_int(_, hop): - if hop.nb_args == 1: - v_str, = hop.inputargs(string_repr) - c_base = inputconst(Signed, 10) - return hop.gendirectcall(ll_int, v_str, c_base) + if hop.nb_args == 1: + v_str, = hop.inputargs(string_repr) + c_base = inputconst(Signed, 10) + return hop.gendirectcall(ll_int, v_str, c_base) if not hop.args_r[1] == rint.signed_repr: raise TyperError, 'base needs to be an int' - v_str, v_base= hop.inputargs(string_repr, rint.signed_repr) - return hop.gendirectcall(ll_int, v_str, v_base) + v_str, v_base= hop.inputargs(string_repr, rint.signed_repr) + return hop.gendirectcall(ll_int, v_str, v_base) def ll_str(s, r): if typeOf(s) == Char: From ericvrp at codespeak.net Fri Aug 5 21:36:41 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 5 Aug 2005 21:36:41 +0200 (CEST) Subject: [pypy-svn] r15709 - in pypy/dist/pypy/translator/llvm2: module test Message-ID: <20050805193641.5FB3127B47@code1.codespeak.net> Author: ericvrp Date: Fri Aug 5 21:36:40 2005 New Revision: 15709 Modified: pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: - refactored to use a template - added some more ZeroDivisionError raising operators Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 5 21:36:40 2005 @@ -24,53 +24,36 @@ """) -extfunctions["%__prepare_ZeroDivisionError"] = ((), """ -fastcc void %__prepare_ZeroDivisionError() { - - %exception_value = call fastcc %structtype.object* %instantiate_ZeroDivisionError() - - %tmp = getelementptr %structtype.object* %exception_value, int 0, uint 0 - %exception_type = load %structtype.object_vtable** %tmp - store %structtype.object_vtable* %exception_type, %structtype.object_vtable** %last_exception_type - store %structtype.object* %exception_value, %structtype.object** %last_exception_value - +for exc in "ZeroDivisionError OverflowError ValueError".split(): + extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ +fastcc void %%__prepare_%(exc)s() { + %%exception_value = call fastcc %%structtype.object* %%instantiate_%(exc)s() + %%tmp = getelementptr %%structtype.object* %%exception_value, int 0, uint 0 + %%exception_type = load %%structtype.object_vtable** %%tmp + store %%structtype.object_vtable* %%exception_type, %%structtype.object_vtable** %%last_exception_type + store %%structtype.object* %%exception_value, %%structtype.object** %%last_exception_value ret void } -""") - -extfunctions["%int_floordiv_zer"] = (("%__prepare_ZeroDivisionError",), """ -fastcc int %int_floordiv_zer(int %x, int %y) { - %cond = seteq int %y, 0 - br bool %cond, label %is_0, label %is_not_0 -is_not_0: - %z = add int %x, %y - ret int %z -is_0: - call fastcc void %__prepare_ZeroDivisionError() - unwind -} - -""") +""" % locals()) -#XXX could use template here -extfunctions["%uint_floordiv_zer"] = (("%__prepare_ZeroDivisionError",), """ -fastcc uint %uint_floordiv_zer(uint %x, uint %y) { - %cond = seteq uint %y, 0 - br bool %cond, label %is_0, label %is_not_0 +for func_inst in "floordiv_zer:div mod_zer:rem".split(): + func, inst = func_inst.split(':') + for type_ in "int uint".split(): + extfunctions["%%%(type_)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ +fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { + %%cond = seteq %(type_)s %%y, 0 + br bool %%cond, label %%is_0, label %%is_not_0 is_not_0: - %z = add uint %x, %y - ret uint %z + %%z = %(inst)s %(type_)s %%x, %%y + ret %(type_)s %%z is_0: - call fastcc void %__prepare_ZeroDivisionError() + call fastcc void %%__prepare_ZeroDivisionError() unwind } -""") +""" % locals()) -#src/int.h:#define OP_INT_FLOORDIV_ZER(x,y,r,err) \ done -#src/int.h:#define OP_UINT_FLOORDIV_ZER(x,y,r,err) \ done +#XXX TODO #src/int.h:#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \ -#src/int.h:#define OP_INT_MOD_ZER(x,y,r,err) \ -#src/int.h:#define OP_UINT_MOD_ZER(x,y,r,err) \ #src/int.h:#define OP_INT_MOD_OVF_ZER(x,y,r,err) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Fri Aug 5 21:36:40 2005 @@ -95,24 +95,46 @@ def test_zerodiv_int(): def zerodiv_int(n): try: - 100/n + r=100/n except ZeroDivisionError: return n+7 - return n+4 + return r f = compile_function(zerodiv_int, [int]) - assert f(1) == zerodiv_int(1) - assert f(0) == zerodiv_int(0) + for i in (-50,0,50): + assert f(i) == zerodiv_int(i) def test_zerodiv_uint(): def zerodiv_uint(n): try: - 100/n + r=100/n except ZeroDivisionError: return n+7 - return n+4 + return r f = compile_function(zerodiv_uint, [r_uint]) - assert f(1) == zerodiv_uint(1) - assert f(0) == zerodiv_uint(0) + for i in (0,50,100): + assert f(i) == zerodiv_uint(i) + +def test_zerodivrem_int(): + def zerodivrem_int(n): + try: + r=100%n + except ZeroDivisionError: + return n+7 + return r + f = compile_function(zerodivrem_int, [int]) + for i in (-50,0,50): + assert f(i) == zerodivrem_int(i) + +def test_zerodivrem_uint(): + def zerodivrem_uint(n): + try: + r=100%n + except ZeroDivisionError: + return n+7 + return r + f = compile_function(zerodivrem_uint, [r_uint]) + for i in (0,50,100): + assert f(i) == zerodivrem_uint(i) def test_reraise1(): def fn(n): From cfbolz at codespeak.net Sat Aug 6 00:50:11 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 00:50:11 +0200 (CEST) Subject: [pypy-svn] r15712 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050805225011.8313127B46@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 00:50:09 2005 New Revision: 15712 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: fixed convert_struct for variable sized structs Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Sat Aug 6 00:50:09 2005 @@ -56,7 +56,11 @@ return address TYPE = lltype.typeOf(_struct) layout = get_layout(TYPE) - size = get_total_size(TYPE) + if TYPE._arrayfld is not None: + inlinedarraylength = len(getattr(_struct, TYPE._arrayfld).items) + size = get_total_size(TYPE, inlinedarraylength) + else: + size = get_total_size(TYPE) if inline_to_addr is not None: startaddr = inline_to_addr else: Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Sat Aug 6 00:50:09 2005 @@ -87,5 +87,18 @@ a = cvter.convert(lla) assert a[0].a[1].a[2].a == a assert [a[i].b for i in range(3)] == [1, 2, 3] + +def test_varsize_struct(): + cvter = LLTypeConverter(lladdress.raw_malloc(1000)) + A = lltype.Array(lltype.Signed) + S = lltype.GcStruct("name", ("v", lltype.Signed), ("a", A)) + lls = lltype.malloc(S, 3) + lls.a[0] = 1 + lls.a[1] = 2 + lls.a[2] = 3 + lls.v = 4 + s = cvter.convert(lls) + assert [s.a[i] for i in range(3)] == [1, 2, 3] + assert s.v == 4 From pedronis at codespeak.net Sat Aug 6 01:21:41 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 6 Aug 2005 01:21:41 +0200 (CEST) Subject: [pypy-svn] r15713 - pypy/dist/pypy/lib Message-ID: <20050805232141.A330027B46@code1.codespeak.net> Author: pedronis Date: Sat Aug 6 01:21:40 2005 New Revision: 15713 Modified: pypy/dist/pypy/lib/_exceptions.py Log: be tidy Modified: pypy/dist/pypy/lib/_exceptions.py ============================================================================== --- pypy/dist/pypy/lib/_exceptions.py (original) +++ pypy/dist/pypy/lib/_exceptions.py Sat Aug 6 01:21:40 2005 @@ -89,15 +89,12 @@ class Exception: """Common base class for all exceptions.""" - # auto-generated code, please check carefully! def __getitem__(self, idx): return self.args[idx] - # auto-generated code, please check carefully! def __init__(self, *args): self.args = args - # auto-generated code, please check carefully! def __str__(self): args = self.args argc = len(args) @@ -126,7 +123,6 @@ class UnicodeTranslateError(UnicodeError): """Unicode translation error.""" - # auto-generated code, please check carefully! def __init__(self, *args): argc = len(args) self.args = args # modified: always assign args, no error check @@ -150,7 +146,6 @@ else: raise TypeError('function takes exactly 4 arguments (%d given)'%argc) - # auto-generated code, please check carefully! def __str__(self): # this is a bad hack, please supply an implementation res = ' '.join([ @@ -168,7 +163,6 @@ class KeyError(LookupError): """Mapping key not found.""" - # auto-generated code, please check carefully! def __str__(self): args = self.args argc = len(args) @@ -191,7 +185,6 @@ class EnvironmentError(StandardError): """Base class for I/O related errors.""" - # auto-generated code, please check carefully! def __init__(self, *args): argc = len(args) self.args = args @@ -248,7 +241,6 @@ print_file_and_line = None text = None - # auto-generated code, please check carefully! def __init__(self, *args): argc = len(args) self.args = args @@ -297,7 +289,6 @@ class SystemExit(Exception): """Request to exit from the interpreter.""" - # auto-generated code, please check carefully! def __init__(self, *args): argc = len(args) if argc == 0: @@ -335,7 +326,6 @@ class UnicodeDecodeError(UnicodeError): """Unicode decoding error.""" - # auto-generated code, please check carefully! def __init__(self, *args): argc = len(args) self.args = args # modified: always assign args, no error check @@ -363,7 +353,6 @@ else: raise TypeError('function takes exactly 5 arguments (%d given)'%argc) - # auto-generated code, please check carefully! def __str__(self): # this is a bad hack, please supply an implementation res = ' '.join([ @@ -412,7 +401,6 @@ class UnicodeEncodeError(UnicodeError): """Unicode encoding error.""" - # auto-generated code, please check carefully! def __init__(self, *args): argc = len(args) self.args = args # modified: always assign args, no error check @@ -440,7 +428,6 @@ else: raise TypeError('function takes exactly 5 arguments (%d given)'%argc) - # auto-generated code, please check carefully! def __str__(self): # this is a bad hack, please supply an implementation res = ' '.join([ From hpk at codespeak.net Sat Aug 6 08:21:08 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 6 Aug 2005 08:21:08 +0200 (CEST) Subject: [pypy-svn] r15715 - in pypy/dist/lib-python: . modified-2.4.1/test Message-ID: <20050806062108.C1CCA27B47@code1.codespeak.net> Author: hpk Date: Sat Aug 6 08:21:07 2005 New Revision: 15715 Added: pypy/dist/lib-python/modified-2.4.1/test/test_sys.py - copied, changed from r15713, pypy/dist/lib-python/2.4.1/test/test_sys.py Modified: pypy/dist/lib-python/failure_list.txt Log: disable refcount test -> test_sys.py passes Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Sat Aug 6 08:21:07 2005 @@ -63,3 +63,6 @@ test_descr FIXED? should be re-run. Were fixed in modified-2.3.4, but then they were somehow lost when we switched to 2.4.1... + +test_sys (FIXED) + refcount test disabled (considered implementation detail from CPython) Copied: pypy/dist/lib-python/modified-2.4.1/test/test_sys.py (from r15713, pypy/dist/lib-python/2.4.1/test/test_sys.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_sys.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_sys.py Sat Aug 6 08:21:07 2005 @@ -207,7 +207,7 @@ self.assertEqual(sys.getdlopenflags(), oldflags+1) sys.setdlopenflags(oldflags) - def test_refcount(self): + def DONT_test_refcount(self): self.assertRaises(TypeError, sys.getrefcount) c = sys.getrefcount(None) n = None From cfbolz at codespeak.net Sat Aug 6 11:18:20 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 11:18:20 +0200 (CEST) Subject: [pypy-svn] r15716 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050806091820.933FC27B47@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 11:18:18 2005 New Revision: 15716 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: fixed convtert_pointer for the case of NULL ptrs. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Sat Aug 6 11:18:18 2005 @@ -4,7 +4,7 @@ from pypy.rpython.memory.lltypesimulation import get_variable_size from pypy.rpython.memory.lltypesimulation import primitive_to_fmt from pypy.rpython.memory.lltypesimulation import get_layout -from pypy.objspace.flow.model import Constant +from pypy.objspace.flow.model import traverse, Link, Constant, SpaceOperation from pypy.rpython import lltype class LLTypeConverter(object): @@ -74,7 +74,10 @@ def convert_pointer(self, _ptr, inline_to_addr): TYPE = lltype.typeOf(_ptr) - addr = self.convert(_ptr._obj) + if _ptr._obj is not None: + addr = self.convert(_ptr._obj) + else: + addr = lladdress.NULL assert isinstance(addr, lladdress.Address) if inline_to_addr is not None: inline_to_addr.address[0] = addr Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Sat Aug 6 11:18:18 2005 @@ -101,4 +101,9 @@ assert [s.a[i] for i in range(3)] == [1, 2, 3] assert s.v == 4 - +def test_nullptr(): + cvter = LLTypeConverter(lladdress.raw_malloc(10)) + S = lltype.GcStruct("name", ("v", lltype.Signed)) + llptr = lltype.nullptr(S) + s = cvter.convert(llptr) + assert not s From tismer at codespeak.net Sat Aug 6 12:46:19 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 6 Aug 2005 12:46:19 +0200 (CEST) Subject: [pypy-svn] r15717 - pypy/dist/pypy/objspace/std Message-ID: <20050806104619.5408727B47@code1.codespeak.net> Author: tismer Date: Sat Aug 6 12:46:18 2005 New Revision: 15717 Modified: pypy/dist/pypy/objspace/std/stringobject.py Log: enabling marshal: had to initialize buffer in the exception case of mul_string_times. This was strange, because this was not consequently always needed. There seems to be some non-determinism. I found no way to reliably reproduce this. When finally trying to remove it, the problem came up, again, so I kept it. Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sat Aug 6 12:46:18 2005 @@ -971,6 +971,9 @@ except (MemoryError,OverflowError,ValueError): # ugh. ValueError is what you get on 64-bit machines for # integers in range(2**31, 2**63). + # XXX needed to initialize buffer for rtyper. Strange, + # because it's need seems to vary! + buffer = [' '] raise OperationError( space.w_OverflowError, space.wrap("repeated string is too long: %d %d" % (input_len,mul) )) pos = 0 From tismer at codespeak.net Sat Aug 6 12:48:26 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 6 Aug 2005 12:48:26 +0200 (CEST) Subject: [pypy-svn] r15718 - pypy/dist/pypy/lib Message-ID: <20050806104826.5CA2827B47@code1.codespeak.net> Author: tismer Date: Sat Aug 6 12:48:25 2005 New Revision: 15718 Modified: pypy/dist/pypy/lib/_osfilewrapper.py Log: enabling marshal: _osfilewrapper had problems with os.write. I had to add an assertion that this is alsway non-negative. Maybe we want to add this info directly to os.write. Modified: pypy/dist/pypy/lib/_osfilewrapper.py ============================================================================== --- pypy/dist/pypy/lib/_osfilewrapper.py (original) +++ pypy/dist/pypy/lib/_osfilewrapper.py Sat Aug 6 12:48:25 2005 @@ -25,6 +25,8 @@ towrite = len(buf) while writecount < towrite: # os.write will raise an error itself + assert writecount >= 0 # annotator hint, don't remove. + # XXX should be tellable in extfunctable writecount += os.write(self.fd, buf[writecount:]) def close(self): From tismer at codespeak.net Sat Aug 6 12:51:57 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 6 Aug 2005 12:51:57 +0200 (CEST) Subject: [pypy-svn] r15719 - in pypy/dist/pypy: module/marshal module/marshal/test objspace/std Message-ID: <20050806105157.67D1A27B47@code1.codespeak.net> Author: tismer Date: Sat Aug 6 12:51:55 2005 New Revision: 15719 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py pypy/dist/pypy/module/marshal/test/test_marshalimpl.py pypy/dist/pypy/objspace/std/marshal_impl.py Log: enabling marshal: I stumble dover some quirks. Empty dicts for instance don't work. Appears like a bug, since we have provisions for empty dicts. There are some other observations and thoughts which got to pypy-dev. Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Sat Aug 6 12:51:55 2005 @@ -144,7 +144,7 @@ space = self.space raise OperationError(space.w_ValueError, space.wrap(msg)) -DONT_USE_MM_HACK = False +DONT_USE_MM_HACK = True # im_func is not RPython :-( class Marshaller(_Base): # _annspecialcase_ = "specialize:ctr_location" # polymorphic @@ -160,9 +160,20 @@ * APPLEVEL_STACK_COST + TEST_CONST) self.cpy_nesting = 0 # contribution to compatibility self.stringtable = {} + # since we currently probably can't reach the stringtable (we can't + # find interned strings), try to convince rtyper that this is + #really a string dict. + s = 'hello' + self.stringtable[s] = space.wrap(s) + del self.stringtable[s] self.stackless = False self._stack = None - self._iddict = {} + #self._iddict = {} + # XXX consider adding the dict later when it is needed. + # XXX I would also love to use an IntDict for this, if + # we had that. Otherwise I'd need to either make strings + # from ids (not all that bad) or use a real dict. + # How expensive would that be? ## currently we cannot use a put that is a bound method ## from outside. Same holds for get. @@ -170,7 +181,8 @@ self.writer.write(s) def atom(self, typecode): - assert type(typecode) is str and len(typecode) == 1 + #assert type(typecode) is str and len(typecode) == 1 + # type(char) not supported self.put(typecode) def atom_int(self, typecode, x): @@ -193,13 +205,16 @@ def atom_strlist(self, typecode, tc2, x): self.atom_int(typecode, len(x)) + atom_str = self.atom_str for item in x: - if type(item) is not str: - self.raise_exc('object with wrong type in strlist') - self.atom_str(tc2, item) + # type(str) seems to be forbidden + #if type(item) is not str: + # self.raise_exc('object with wrong type in strlist') + atom_str(tc2, item) def start(self, typecode): - assert type(typecode) is str and len(typecode) == 1 + #assert type(typecode) is str and len(typecode) == 1 + # type(char) not supported self.put(typecode) def put_short(self, x): @@ -268,18 +283,12 @@ def put_list_w(self, list_w, lng): if DONT_USE_MM_HACK: - # inlining makes no sense without the hack - self.nesting += 1 - self.put_int(lng) - idx = 0 - while idx < lng: - self.put_w_obj(list_w[idx]) - idx += 1 - self.nesting -= 1 - return - - # inlined version, two stack levels, only! - self.nesting += 2 + nest = 4 + marshal_w = self.space.marshal_w + else: + nest = 2 + # inlined version, two stack levels, only, with the hack! + self.nesting += nest self.put_int(lng) idx = 0 space = self.space @@ -290,14 +299,17 @@ if do_nested: while idx < lng: w_obj = list_w[idx] - self._get_mm_marshal(w_obj)(space, w_obj, self) + if DONT_USE_MM_HACK: + marshal_w(w_obj, self) + else: + self._get_mm_marshal(w_obj)(space, w_obj, self) idx += 1 else: while idx < lng: w_obj = list_w[idx] self._run_stackless(w_obj) idx += 1 - self.nesting -= 2 + self.nesting -= nest if CPYTHON_COMPATIBLE: self.cpy_nesting -= 1 @@ -306,7 +318,19 @@ def invalid_typecode(space, u, tc): - u.raise_exc('invalid typecode in unmarshal: %r' % tc) + # %r not supported in rpython + #u.raise_exc('invalid typecode in unmarshal: %r' % tc) + c = ord(tc) + if c < 32 or c > 126: + s = '\\x' + hex(c) + elif tc == '\\': + s = r'\\' + else: + s = tc + q = "'" + if s[0] == "'": + q = '"' + u.raise_exc('invalid typecode in unmarshal: ' + q + s + q) def register(codes, func): """NOT_RPYTHON""" Modified: pypy/dist/pypy/module/marshal/test/test_marshalimpl.py ============================================================================== --- pypy/dist/pypy/module/marshal/test/test_marshalimpl.py (original) +++ pypy/dist/pypy/module/marshal/test/test_marshalimpl.py Sat Aug 6 12:51:55 2005 @@ -10,7 +10,7 @@ for do_hack in (False, True): interp_marshal.DONT_USE_MM_HACK = not do_hack if not do_hack: - interp_cost = 5 + interp_cost = 4 else: interp_cost = 2 stacklimit = interp_marshal.nesting_limit - (curdepth + 1) * app_cost - interp_marshal.TEST_CONST Modified: pypy/dist/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/dist/pypy/objspace/std/marshal_impl.py (original) +++ pypy/dist/pypy/objspace/std/marshal_impl.py Sat Aug 6 12:51:55 2005 @@ -30,7 +30,7 @@ from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.unicodeobject import W_UnicodeObject -import longobject +import longobject, dictobject from pypy.objspace.std.strutil import string_to_float from pypy.module.marshal.interp_marshal import register @@ -344,14 +344,18 @@ m.atom(TYPE_NULL) def unmarshal_Dict(space, u, tc): - items_w = [] + # since primitive lists are not optimized and we don't know + # the dict size in advance, use the dict's setitem instead + # of building a list of tuples. + w_dic = W_DictObject(space, []) + setter = dictobject.setitem__Dict_ANY_ANY while 1: w_key = u.get_w_obj(True) if w_key is None: break w_value = u.get_w_obj(False) - items_w.append( (w_key, w_value) ) - return W_DictObject(space, items_w) + setter(space, w_dic, w_key, w_value) + return w_dic register(TYPE_DICT, unmarshal_Dict) def unmarshal_NULL(self, u, tc): From tismer at codespeak.net Sat Aug 6 12:53:51 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 6 Aug 2005 12:53:51 +0200 (CEST) Subject: [pypy-svn] r15720 - in pypy/dist/pypy: interpreter module/__builtin__ Message-ID: <20050806105351.E4D5E27B47@code1.codespeak.net> Author: tismer Date: Sat Aug 6 12:53:50 2005 New Revision: 15720 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/module/__builtin__/importing.py Log: enabling marshal: these files were just changed for reactivation. For some other observations and thoughts see my post to pypy-dev. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Sat Aug 6 12:53:50 2005 @@ -164,7 +164,7 @@ pass modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', - 'array'] + 'array', 'marshal'] if self.options.nofaking: modules.append('posix') Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Sat Aug 6 12:53:50 2005 @@ -48,7 +48,7 @@ pyfile_exist = False pycfile = filepart + ".pyc" - if 0: # os.path.exists(pycfile): # DISABLED PYC FILES FOR NOW + if os.path.exists(pycfile): pyc_state = check_compiled_module(space, pyfile, pyfile_ts, pycfile) pycfile_exists = pyc_state >= 0 pycfile_ts_valid = pyc_state > 0 and pyfile_exist @@ -359,16 +359,15 @@ w = space.wrap pycode = parse_source_module(space, pathname, osfile) - w_dict = space.getattr(w_mod, w('__dict__')) + w_dict = space.getattr(w_mod, w('__dict__')) space.call_method(w_dict, 'setdefault', w('__builtins__'), w(space.builtin)) pycode.exec_code(space, w_dict, w_dict) - if 0: # DISABLED PYC FILES FOR NOW - mtime = os.fstat(osfile.fd)[stat.ST_MTIME] - cpathname = pathname + 'c' - write_compiled_module(space, pycode, cpathname, mtime) + mtime = os.fstat(osfile.fd)[stat.ST_MTIME] + cpathname = pathname + 'c' + write_compiled_module(space, pycode, cpathname, mtime) return w_mod @@ -485,7 +484,6 @@ pass #XXX debug #print "indeed writing", cpathname - w_M = space.getattr(w_marshal, space.wrap('dumps')) try: w_str = space.call_method(w_marshal, 'dumps', space.wrap(co)) except OperationError: From cfbolz at codespeak.net Sat Aug 6 13:21:00 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 13:21:00 +0200 (CEST) Subject: [pypy-svn] r15721 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050806112100.41FA927B50@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 13:20:58 2005 New Revision: 15721 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: added function ptrs + test Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Sat Aug 6 13:20:58 2005 @@ -7,9 +7,9 @@ log = py.log.Producer("lltypesim") -primitive_to_fmt = {lltype.Signed: "i", - lltype.Unsigned: "I", - lltype.Char: "c", +primitive_to_fmt = {lltype.Signed: "i", + lltype.Unsigned: "I", + lltype.Char: "c", } #returns some sort of layout information that is useful for the simulatorptr @@ -28,8 +28,12 @@ return layout elif isinstance(TYPE, lltype.Array): return (get_fixed_size(lltype.Signed), get_fixed_size(TYPE.OF)) + elif isinstance(TYPE, lltype.OpaqueType): + return "i" + elif isinstance(TYPE, lltype.FuncType): + return "i" else: - assert 0, "not yet implemented" + assert 0, "type %s not yet implemented" % (TYPE, ) def get_fixed_size(TYPE): if isinstance(TYPE, lltype.Primitive): @@ -40,6 +44,10 @@ return get_layout(TYPE)["_size"] elif isinstance(TYPE, lltype.Array): return get_fixed_size(lltype.Unsigned) + elif isinstance(TYPE, lltype.OpaqueType): + return get_fixed_size(lltype.Unsigned) + elif isinstance(TYPE, lltype.FuncType): + return get_fixed_size(lltype.Unsigned) assert 0, "not yet implemented" def get_variable_size(TYPE): @@ -52,6 +60,10 @@ return get_variable_size(TYPE._flds[TYPE._arrayfld]) else: return 0 + elif isinstance(TYPE, lltype.OpaqueType): + return 0 + elif isinstance(TYPE, lltype.FuncType): + return 0 else: assert 0, "not yet implemented" @@ -165,6 +177,20 @@ return raise TypeError("%r instance is not an array" % (self._T,)) + def __call__(self, *args): + if isinstance(self._T, lltype.FuncType): + if len(args) != len(self._T.ARGS): + raise TypeError,"calling %r with wrong argument number: %r" % (self._T, args) + for a, ARG in zip(args, self._T.ARGS): + if lltype.typeOf(a) != ARG: + raise TypeError,"calling %r with wrong argument types: %r" % (self._T, args) + callb = self._address.attached[0]._callable + if callb is None: + raise RuntimeError,"calling undefined function" + return callb(*args) + raise TypeError("%r instance is not a function" % (self._T,)) + + def __len__(self): if isinstance(self._T, lltype.Array): return self._address.signed[0] @@ -216,3 +242,13 @@ def nullptr(T): return simulatorptr(lltype.Ptr(T), lladdress.NULL) +def functionptr(TYPE, name, **attrs): + if not isinstance(TYPE, lltype.FuncType): + raise TypeError, "functionptr() for FuncTypes only" + try: + hash(tuple(attrs.items())) + except TypeError: + raise TypeError("'%r' must be hashable"%attrs) + addr = lladdress.raw_malloc(get_total_size(TYPE)) + addr.attached[0] = lltype._func(TYPE, _name=name, **attrs) + return simulatorptr(lltype.Ptr(TYPE), addr) Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Sat Aug 6 13:20:58 2005 @@ -296,3 +296,9 @@ s1.sub.x = 1 assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1) +def test_function_ptr(): + def f(x, y): + return x + y + F = lltype.FuncType((lltype.Signed, lltype.Signed), lltype.Signed) + funcptr = functionptr(F, "add", _callable=f) + assert funcptr(1, 2) == 3 From cfbolz at codespeak.net Sat Aug 6 13:53:09 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 13:53:09 +0200 (CEST) Subject: [pypy-svn] r15722 - pypy/dist/pypy/rpython/memory Message-ID: <20050806115309.191AC27B50@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 13:53:07 2005 New Revision: 15722 Modified: pypy/dist/pypy/rpython/memory/simulator.py Log: prevent find_block from looping forever. Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Sat Aug 6 13:53:07 2005 @@ -67,6 +67,8 @@ self.size_of_simulated_ram = ram_size def find_block(self, address): + if address >= self.freememoryaddress: + raise MemorySimulatorError, "trying to access memory not malloc'ed" lo = 0 hi = len(self.blocks) while lo < hi: From cfbolz at codespeak.net Sat Aug 6 13:54:48 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 13:54:48 +0200 (CEST) Subject: [pypy-svn] r15723 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050806115448.A78A827B50@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 13:54:47 2005 New Revision: 15723 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: added possiblity to convert function ptrs. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Sat Aug 6 13:54:47 2005 @@ -1,12 +1,16 @@ +import autopath from pypy.rpython.memory import lladdress from pypy.rpython.memory.lltypesimulation import simulatorptr, get_total_size from pypy.rpython.memory.lltypesimulation import get_fixed_size from pypy.rpython.memory.lltypesimulation import get_variable_size from pypy.rpython.memory.lltypesimulation import primitive_to_fmt from pypy.rpython.memory.lltypesimulation import get_layout -from pypy.objspace.flow.model import traverse, Link, Constant, SpaceOperation +from pypy.objspace.flow.model import traverse, Link, Constant, Block +from pypy.objspace.flow.model import Constant from pypy.rpython import lltype +import struct + class LLTypeConverter(object): def __init__(self, address): self.converted = {} @@ -24,8 +28,14 @@ return self.convert_struct(val_or_ptr, inline_to_addr) elif isinstance(TYPE, lltype.Ptr): return self.convert_pointer(val_or_ptr, inline_to_addr) + elif isinstance(TYPE, lltype.OpaqueType): + return self.convert_object(val_or_ptr, inline_to_addr) + elif isinstance(TYPE, lltype.FuncType): + return self.convert_object(val_or_ptr, inline_to_addr) + elif isinstance(TYPE, lltype.PyObjectType): + return self.convert_object(val_or_ptr, inline_to_addr) else: - assert 0, "not yet implemented" + assert 0, "don't know about %s" % (val_or_ptr, ) def convert_array(self, _array, inline_to_addr): if _array in self.converted: @@ -82,3 +92,14 @@ if inline_to_addr is not None: inline_to_addr.address[0] = addr return simulatorptr(TYPE, addr) + + def convert_object(self, _obj, inline_to_addr): + if inline_to_addr is not None: + inline_to_addr.attached[0] = _obj + return inline_to_addr + else: + addr = self.curraddress + addr.attached[0] = _obj + self.curraddress += struct.calcsize("i") + return addr + Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Sat Aug 6 13:54:47 2005 @@ -107,3 +107,14 @@ llptr = lltype.nullptr(S) s = cvter.convert(llptr) assert not s + +def test_funcptr(): + def f(x, y): + return x + y + F = lltype.FuncType((lltype.Signed, lltype.Signed), lltype.Signed) + llfuncptr = lltype.functionptr(F, "add", _callable=f) + assert llfuncptr(1, 2) == 3 + cvter = LLTypeConverter(lladdress.raw_malloc(10)) + fpter = cvter.convert(llfuncptr) + assert fpter(1, 2) == 3 + From pedronis at codespeak.net Sat Aug 6 14:06:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 6 Aug 2005 14:06:13 +0200 (CEST) Subject: [pypy-svn] r15724 - pypy/dist/pypy/rpython Message-ID: <20050806120613.38A4027B54@code1.codespeak.net> Author: pedronis Date: Sat Aug 6 14:06:12 2005 New Revision: 15724 Modified: pypy/dist/pypy/rpython/extfunctable.py Log: os.write result is positive Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Sat Aug 6 14:06:12 2005 @@ -54,6 +54,10 @@ def noneannotation(*args): return None +def posannotation(*args): + from pypy.annotation.model import SomeInteger + return SomeInteger(nonneg=True) + def statannotation(*args): from pypy.annotation.model import SomeInteger, SomeTuple return SomeTuple((SomeInteger(),)*10) @@ -69,7 +73,7 @@ # external function declarations declare(os.open , int , 'll_os/open') declare(os.read , str , 'll_os/read') -declare(os.write , int , 'll_os/write') +declare(os.write , posannotation , 'll_os/write') declare(os.close , noneannotation, 'll_os/close') declare(os.getcwd , str , 'll_os/getcwd') declare(os.dup , int , 'll_os/dup') From pedronis at codespeak.net Sat Aug 6 15:09:25 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 6 Aug 2005 15:09:25 +0200 (CEST) Subject: [pypy-svn] r15725 - pypy/dist/lib-python Message-ID: <20050806130925.61B7F27B54@code1.codespeak.net> Author: pedronis Date: Sat Aug 6 15:09:23 2005 New Revision: 15725 Modified: pypy/dist/lib-python/failure_list.txt Log: test_marshal fails! Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Sat Aug 6 15:09:23 2005 @@ -32,6 +32,9 @@ still crashes because it does a str() on a a mutating dict which results in a RuntimeError, what does CPython output in this case? +test_marshal + even with our new complete marshall support enabled this one has + failures test_tuple etc do we want to support x is x*1 where x is exactly a tuple? From pedronis at codespeak.net Sat Aug 6 16:11:33 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 6 Aug 2005 16:11:33 +0200 (CEST) Subject: [pypy-svn] r15728 - pypy/dist/pypy/module/__builtin__ Message-ID: <20050806141133.B631727B55@code1.codespeak.net> Author: pedronis Date: Sat Aug 6 16:11:32 2005 New Revision: 15728 Modified: pypy/dist/pypy/module/__builtin__/importing.py Log: disabling pyc files for now again, I was getting unexpected from imports: EOFError: EOF read where object expected Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Sat Aug 6 16:11:32 2005 @@ -30,6 +30,8 @@ import stat +PYC_ONOFF = False + def info_modtype(space ,filepart): """ calculate whether the .py file exists, the .pyc file exists @@ -48,7 +50,7 @@ pyfile_exist = False pycfile = filepart + ".pyc" - if os.path.exists(pycfile): + if PYC_ONOFF and os.path.exists(pycfile): pyc_state = check_compiled_module(space, pyfile, pyfile_ts, pycfile) pycfile_exists = pyc_state >= 0 pycfile_ts_valid = pyc_state > 0 and pyfile_exist @@ -365,9 +367,10 @@ w(space.builtin)) pycode.exec_code(space, w_dict, w_dict) - mtime = os.fstat(osfile.fd)[stat.ST_MTIME] - cpathname = pathname + 'c' - write_compiled_module(space, pycode, cpathname, mtime) + if PYC_ONOFF: + mtime = os.fstat(osfile.fd)[stat.ST_MTIME] + cpathname = pathname + 'c' + write_compiled_module(space, pycode, cpathname, mtime) return w_mod From pedronis at codespeak.net Sat Aug 6 16:21:18 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 6 Aug 2005 16:21:18 +0200 (CEST) Subject: [pypy-svn] r15729 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050806142118.1963F27B51@code1.codespeak.net> Author: pedronis Date: Sat Aug 6 16:21:16 2005 New Revision: 15729 Added: pypy/dist/lib-python/modified-2.4.1/test/test_userstring.py - copied, changed from r15720, pypy/dist/lib-python/2.4.1/test/test_userstring.py Modified: pypy/dist/lib-python/modified-2.4.1/test/string_tests.py Log: refactorings for test_userstring Modified: pypy/dist/lib-python/modified-2.4.1/test/string_tests.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/string_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/string_tests.py Sat Aug 6 16:21:16 2005 @@ -45,11 +45,15 @@ else: return obj + # single this out, because UserString cannot cope with fixed args + fixargs = fixtype + subclasscheck = True + # check that object.method(*args) returns result def checkequal(self, result, object, methodname, *args): result = self.fixtype(result) object = self.fixtype(object) - args = self.fixtype(args) + args = self.fixargs(args) realresult = getattr(object, methodname)(*args) self.assertEqual( result, @@ -57,7 +61,7 @@ ) # if the original is returned make sure that # this doesn't happen with subclasses - if object == realresult: + if object == realresult and self.subclasscheck: class subtype(self.__class__.type2test): pass object = subtype(object) @@ -67,17 +71,26 @@ # check that op(*args) returns result def checkop(self, result, op, *args): result = self.fixtype(result) - args = self.fixtype(args) - realresult = op(*args) + object = self.fixtype(args[0]) + args = self.fixargs(args[1:]) + realresult = op(object, *args) self.assertEqual( result, realresult ) + # if the original is returned make sure that + # this doesn't happen with subclasses + if object == realresult and self.subclasscheck: + class subtype(self.__class__.type2test): + pass + object = subtype(object) + realresult = op(object, *args) + self.assert_(object is not realresult) # check that object.method(*args) raises exc def checkraises(self, exc, object, methodname, *args): object = self.fixtype(object) - args = self.fixtype(args) + args = self.fixargs(args) self.assertRaises( exc, getattr(object, methodname), @@ -86,23 +99,26 @@ # check that op(*args) raises exc def checkopraises(self, exc, op, *args): - args = self.fixtype(args) + object = self.fixtype(args[0]) + args = self.fixargs(args[1:]) self.assertRaises( exc, op, + object, *args ) # call object.method(*args) without any checks def checkcall(self, object, methodname, *args): object = self.fixtype(object) - args = self.fixtype(args) + args = self.fixargs(args) getattr(object, methodname)(*args) # call op(*args) without any checks def checkopcall(self, op, *args): - args = self.fixtype(args) - op(*args) + object = self.fixtype(args[0]) + args = self.fixargs(args[1:]) + op(object, *args) def test_hash(self): # SF bug 1054139: += optimization was not invalidating cached hash value Copied: pypy/dist/lib-python/modified-2.4.1/test/test_userstring.py (from r15720, pypy/dist/lib-python/2.4.1/test/test_userstring.py) ============================================================================== --- pypy/dist/lib-python/2.4.1/test/test_userstring.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_userstring.py Sat Aug 6 16:21:16 2005 @@ -16,32 +16,8 @@ type2test = UserString - # Overwrite the three testing methods, because UserString - # can't cope with arguments propagated to UserString - # (and we don't test with subclasses) - def checkequal(self, result, object, methodname, *args): - result = self.fixtype(result) - object = self.fixtype(object) - # we don't fix the arguments, because UserString can't cope with it - realresult = getattr(object, methodname)(*args) - self.assertEqual( - result, - realresult - ) - - def checkraises(self, exc, object, methodname, *args): - object = self.fixtype(object) - # we don't fix the arguments, because UserString can't cope with it - self.assertRaises( - exc, - getattr(object, methodname), - *args - ) - - def checkcall(self, object, methodname, *args): - object = self.fixtype(object) - # we don't fix the arguments, because UserString can't cope with it - getattr(object, methodname)(*args) + fixargs = lambda args: args + subclasscheck = False def test_main(): test_support.run_unittest(UserStringTest) From arigo at codespeak.net Sat Aug 6 16:32:31 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Aug 2005 16:32:31 +0200 (CEST) Subject: [pypy-svn] r15731 - pypy/dist/pypy/translator/c/src Message-ID: <20050806143231.0B35527B51@code1.codespeak.net> Author: arigo Date: Sat Aug 6 16:32:28 2005 New Revision: 15731 Modified: pypy/dist/pypy/translator/c/src/ll_time.h Log: Don't include on Windows. (thanks xorAxAx) Modified: pypy/dist/pypy/translator/c/src/ll_time.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_time.h (original) +++ pypy/dist/pypy/translator/c/src/ll_time.h Sat Aug 6 16:32:28 2005 @@ -1,8 +1,10 @@ /************************************************************/ /*** C header subsection: time module ***/ -#include #include +#ifndef MS_WINDOWS +# include +#endif /****** clock() ******/ From tismer at codespeak.net Sat Aug 6 16:33:23 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 6 Aug 2005 16:33:23 +0200 (CEST) Subject: [pypy-svn] r15732 - pypy/dist/pypy/lib Message-ID: <20050806143323.CDB2D27B51@code1.codespeak.net> Author: tismer Date: Sat Aug 6 16:33:20 2005 New Revision: 15732 Modified: pypy/dist/pypy/lib/_osfilewrapper.py Log: removed annotator hint, after os.write is now unsigned. thanks, Samuele! Modified: pypy/dist/pypy/lib/_osfilewrapper.py ============================================================================== --- pypy/dist/pypy/lib/_osfilewrapper.py (original) +++ pypy/dist/pypy/lib/_osfilewrapper.py Sat Aug 6 16:33:20 2005 @@ -25,8 +25,6 @@ towrite = len(buf) while writecount < towrite: # os.write will raise an error itself - assert writecount >= 0 # annotator hint, don't remove. - # XXX should be tellable in extfunctable writecount += os.write(self.fd, buf[writecount:]) def close(self): From pedronis at codespeak.net Sat Aug 6 16:36:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 6 Aug 2005 16:36:59 +0200 (CEST) Subject: [pypy-svn] r15734 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050806143659.4508227B51@code1.codespeak.net> Author: pedronis Date: Sat Aug 6 16:36:57 2005 New Revision: 15734 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_userstring.py Log: oops Modified: pypy/dist/lib-python/modified-2.4.1/test/test_userstring.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_userstring.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_userstring.py Sat Aug 6 16:36:57 2005 @@ -16,7 +16,7 @@ type2test = UserString - fixargs = lambda args: args + fixargs = lambda self, args: args subclasscheck = False def test_main(): From arigo at codespeak.net Sat Aug 6 17:39:41 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Aug 2005 17:39:41 +0200 (CEST) Subject: [pypy-svn] r15738 - in pypy/dist/pypy/rpython: . test Message-ID: <20050806153941.C7FAD27B54@code1.codespeak.net> Author: arigo Date: Sat Aug 6 17:39:38 2005 New Revision: 15738 Modified: pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/remptydict.py pypy/dist/pypy/rpython/test/test_remptydict.py Log: Empty dicts: missed support for rtype_newdict (only supported prebuilt empty dicts). Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Sat Aug 6 17:39:38 2005 @@ -43,7 +43,7 @@ rtyper.getrepr(dictkey.s_value), rtyper.getrepr(dictvalue.s_value)) elif isinstance(s_key, annmodel.SomeImpossibleValue): - return remptydict.EmptyDictRepr() + return remptydict.emptydict_repr elif (s_key.__class__ is annmodel.SomeObject and s_key.knowntype == object and s_value.__class__ is annmodel.SomeObject and s_value.knowntype == object): return robject.pyobj_repr @@ -293,6 +293,8 @@ if r_dict == robject.pyobj_repr: # special case: SomeObject: SomeObject dicts! cdict = hop.inputconst(robject.pyobj_repr, dict) return hop.genop('simple_call', [cdict], resulttype = robject.pyobj_repr) + if r_dict == remptydict.emptydict_repr: # other special case: empty dicts + return hop.inputconst(lltype.Void, {}) if not isinstance(r_dict, StrDictRepr): raise rmodel.TyperError("cannot create non-StrDicts, got %r" %(r_dict,)) c1 = hop.inputconst(lltype.Void, r_dict.lowleveltype) Modified: pypy/dist/pypy/rpython/remptydict.py ============================================================================== --- pypy/dist/pypy/rpython/remptydict.py (original) +++ pypy/dist/pypy/rpython/remptydict.py Sat Aug 6 17:39:38 2005 @@ -12,3 +12,6 @@ def rtype_len(self, hop): return hop.inputconst(lltype.Signed, 0) + + +emptydict_repr = EmptyDictRepr() Modified: pypy/dist/pypy/rpython/test/test_remptydict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_remptydict.py (original) +++ pypy/dist/pypy/rpython/test/test_remptydict.py Sat Aug 6 17:39:38 2005 @@ -5,8 +5,9 @@ class A: pass a = A() - a.d = {} + a.d1 = {} def func(): - return bool(a.d) - res = interpret(func, []) + a.d2 = {} + return bool(a.d1) or bool(a.d2) + res = interpret(func, [], view=True) assert res is False From cfbolz at codespeak.net Sat Aug 6 17:42:33 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 17:42:33 +0200 (CEST) Subject: [pypy-svn] r15739 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050806154233.86FFB27B54@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 17:42:31 2005 New Revision: 15739 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: added bools. Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Sat Aug 6 17:42:31 2005 @@ -10,6 +10,7 @@ primitive_to_fmt = {lltype.Signed: "i", lltype.Unsigned: "I", lltype.Char: "c", + lltype.Bool: "B", } #returns some sort of layout information that is useful for the simulatorptr @@ -32,6 +33,8 @@ return "i" elif isinstance(TYPE, lltype.FuncType): return "i" + elif isinstance(TYPE, lltype.PyObjectType): + return "i" else: assert 0, "type %s not yet implemented" % (TYPE, ) @@ -48,6 +51,8 @@ return get_fixed_size(lltype.Unsigned) elif isinstance(TYPE, lltype.FuncType): return get_fixed_size(lltype.Unsigned) + elif isinstance(TYPE, lltype.PyObjectType): + return get_fixed_size(lltype.Unsigned) assert 0, "not yet implemented" def get_variable_size(TYPE): @@ -64,6 +69,8 @@ return 0 elif isinstance(TYPE, lltype.FuncType): return 0 + elif isinstance(TYPE, lltype.PyObjectType): + return 0 else: assert 0, "not yet implemented" Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Sat Aug 6 17:42:31 2005 @@ -4,17 +4,21 @@ def test_struct(): S0 = lltype.GcStruct("s0", ('a', lltype.Signed), - ('b', lltype.Signed), ('c', lltype.Char)) + ('b', lltype.Signed), ('c', lltype.Char), + ('d', lltype.Bool)) s0 = malloc(S0) assert s0.a == 0 assert s0.b == 0 assert s0.c == '\x00' + assert s0.b == 0 s0.a = 42 s0.b = 43 s0.c = 'x' + s0.d = True assert s0.a == 42 assert s0.b == 43 assert s0.c == 'x' + assert s0.d == 1 s0.a = 1 s0.b = s0.a assert s0.a == 1 @@ -34,7 +38,6 @@ assert [x[z].v for z in range(3)] == [1, 2, 3] - def define_list(T): List_typ = lltype.GcStruct( "list", ("items", lltype.Ptr(lltype.GcArray(('item',T))))) From cfbolz at codespeak.net Sat Aug 6 17:54:32 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 17:54:32 +0200 (CEST) Subject: [pypy-svn] r15740 - in pypy/dist/pypy/rpython: . memory memory/test Message-ID: <20050806155432.DB98E27B54@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 17:54:29 2005 New Revision: 15740 Added: pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py - copied, changed from r15720, pypy/dist/pypy/rpython/test/test_llinterp.py Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: added FlowGraphConstantConverter which looks through a flow graph and converts all constants in it to use the simulating lltype implementation on top of the memory simulator. this can then be used to use the lltypesimulation in llinterp even when constants present. A lot of tests pass now, exceptions are giving me trouble -- I'm running out of time, will fix this tommorow. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sat Aug 6 17:54:29 2005 @@ -16,7 +16,9 @@ class LLInterpreter(object): """ low level interpreter working with concrete values. """ - def __init__(self, flowgraphs, typer, lltype=lltype): + def __init__(self, flowgraphs, typer, lltype=lltype, prepare_graphs=None): + if prepare_graphs is not None: + prepare_graphs(flowgraphs) self.flowgraphs = flowgraphs self.bindings = {} self.typer = typer Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Sat Aug 6 17:54:29 2005 @@ -103,3 +103,100 @@ self.curraddress += struct.calcsize("i") return addr +class FlowGraphConstantConverter(object): + def __init__(self, flowgraphs): + self.flowgraphs = flowgraphs + self.memory = lladdress.NULL + self.cvter = None + self.total_size = 0 + + def collect_constants(self): + constants = {} + def collect_args(args): + for arg in args: + if isinstance(arg, Constant): + constants[arg] = None + def visit(obj): + if isinstance(obj, Link): + collect_args(obj.args) + elif isinstance(obj, Block): + for op in obj.operations: + collect_args(op.args) + for graph in self.flowgraphs.itervalues(): + traverse(visit, graph) + self.constants = constants + + def calculate_size(self): + total_size = 0 + seen = {} + candidates = [const.value for const in self.constants.iterkeys()] + while candidates: + cand = candidates.pop() + if isinstance(cand, lltype._ptr): + if cand: + candidates.append(cand._obj) + continue + elif isinstance(cand, lltype.LowLevelType): + continue + elif isinstance(cand, str): + continue + elif isinstance(lltype.typeOf(cand), lltype.Primitive): + continue + elif cand in seen: + continue + elif isinstance(cand, lltype._array): + seen[cand] = True + length = len(cand.items) + total_size += get_total_size(cand._TYPE, length) + for item in cand.items: + candidates.append(item) + elif isinstance(cand, lltype._struct): + seen[cand] = True + TYPE = cand._TYPE + if TYPE._arrayfld is not None: + total_size += get_total_size( + TYPE, len(getattr(cand, TYPE._arrayfld).items)) + else: + total_size += get_total_size(TYPE) + for name in TYPE._flds: + candidates.append(getattr(cand, name)) + elif isinstance(cand, lltype._opaque): + total_size += struct.calcsize("i") + elif isinstance(cand, lltype._func): + total_size += struct.calcsize("i") + elif isinstance(cand, lltype._pyobject): + total_size += struct.calcsize("i") + else: + assert 0, "don't know about %s %s" % (cand, cand.__class__) + self.total_size = total_size + + def convert_constants(self): + self.memory = lladdress.raw_malloc(self.total_size) + self.cvter = LLTypeConverter(self.memory) + for constant in self.constants.iterkeys(): + if isinstance(constant.value, lltype.LowLevelType): + self.constants[constant] = constant.value + elif isinstance(constant.value, str): + self.constants[constant] = constant.value + else: + self.constants[constant] = self.cvter.convert(constant.value) + + def patch_graphs(self): + def patch_consts(args): + for arg in args: + if isinstance(arg, Constant) and arg in self.constants: + arg.value = self.constants[arg] + def visit(obj): + if isinstance(obj, Link): + patch_consts(obj.args) + elif isinstance(obj, Block): + for op in obj.operations: + patch_consts(op.args) + for graph in self.flowgraphs.itervalues(): + traverse(visit, graph) + + def convert(self): + self.collect_constants() + self.calculate_size() + self.convert_constants() + self.patch_graphs() Added: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/gclltype.py Sat Aug 6 17:54:29 2005 @@ -0,0 +1,35 @@ +from pypy.rpython.lltype import LowLevelType, ContainerType, Struct, GcStruct +from pypy.rpython.lltype import Array, GcArray, FuncType, OpaqueType +from pypy.rpython.lltype import RuntimeTypeInfo, PyObjectType, PyObject +from pypy.rpython.lltype import GC_CONTAINER +from pypy.rpython.lltype import Signed, Unsigned, Float, Char, Bool, Void +from pypy.rpython.lltype import UniChar, Ptr, typeOf, InvalidCast + +from pypy.rpython.memory.lltypesimulation import cast_pointer +from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr +from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr + + +def notimplemented(*args, **kwargs): + raise NotImplemented + +# the following names might have to be imported from lltype as well +# ForwardReference, GcForwardReference, castable, parentlink + +ForwardReference = GcForwardReference = castable = parentlink = notimplemented + + +# the following names from lltype will probably have to be implemented yet: +# opaqueptr, pyobjectptr, attachRuntimeTypeInfo, getRuntimeTypeInfo, +# runtime_type_info + +opaqueptr = pyobjectptr = attachRuntimeTypeInfo = notimplemented +getRuntimeTypeInfo = runtime_type_info = notimplemented + +del notimplemented + +def prepare_graphs(translator): + from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter + fgcc = FlowGraphConstantConverter(translator) + fgcc.convert() + Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Sat Aug 6 17:54:29 2005 @@ -184,6 +184,11 @@ return raise TypeError("%r instance is not an array" % (self._T,)) + def _getobj(self): + assert isinstance(self._T, (lltype.FuncType, lltype.PyObjectType)) + return self._address.attached[0] + _obj = property(_getobj) + def __call__(self, *args): if isinstance(self._T, lltype.FuncType): if len(args) != len(self._T.ARGS): Copied: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (from r15720, pypy/dist/pypy/rpython/test/test_llinterp.py) ============================================================================== --- pypy/dist/pypy/rpython/test/test_llinterp.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Sat Aug 6 17:54:29 2005 @@ -9,6 +9,9 @@ from pypy.rpython import rstr from pypy.annotation.model import lltype_to_annotation from pypy.rpython.rarithmetic import r_uint, ovfcheck +from pypy.rpython.memory import gclltype + +from pypy.rpython.test.test_llinterp import find_exception, timelog, gengraph # switch on logging of interp to show more info on failing tests @@ -19,39 +22,6 @@ def teardown_module(mod): py.log._setstate(mod.logstate) -def find_exception(exc): - assert isinstance(exc, LLException) - import exceptions - klass, inst = exc.args - func = typer.getexceptiondata().ll_pyexcclass2exc - for cls in exceptions.__dict__.values(): - if type(cls) is type(Exception): - if func(pyobjectptr(cls)).typeptr == klass: - return cls - -def timelog(prefix, call, *args, **kwds): - #import time - #print prefix, "...", - #start = time.time() - res = call(*args, **kwds) - #elapsed = time.time() - start - #print "%.2f secs" %(elapsed,) - return res - -def gengraph(func, argtypes=[], viewbefore=False, policy=None): - t = Translator(func) - - timelog("annotating", t.annotate, argtypes, policy=policy) - if viewbefore: - t.annotator.simplify() - t.view() - global typer # we need it for find_exception - typer = RPythonTyper(t.annotator) - timelog("rtyper-specializing", typer.specialize) - #t.view() - timelog("checking graphs", t.checkgraphs) - return t, typer - _lastinterpreted = [] _tcache = {} def interpret(func, values, view=False, viewbefore=False, policy=None, someobjects=False): @@ -70,7 +40,8 @@ t, typer = gengraph(func, [annotation(x) for x in values], viewbefore, policy) - interp = LLInterpreter(t.flowgraphs, typer) + interp = LLInterpreter(t.flowgraphs, typer, gclltype, + gclltype.prepare_graphs) _tcache[key] = (t, interp) # keep the cache small _lastinterpreted.append(key) @@ -104,7 +75,7 @@ res = interpret(simple_ifs, [1]) assert res == 42 -def test_raise(): +def DONOTtest_raise(): res = interpret(raise_exception, [41]) assert res == 41 info = raises(LLException, interpret, raise_exception, [42]) @@ -112,7 +83,7 @@ info = raises(LLException, interpret, raise_exception, [43]) assert find_exception(info.value) is ValueError -def test_call_raise(): +def DONOTtest_call_raise(): res = interpret(call_raise, [41]) assert res == 41 info = raises(LLException, interpret, call_raise, [42]) @@ -120,7 +91,7 @@ info = raises(LLException, interpret, call_raise, [43]) assert find_exception(info.value) is ValueError -def test_call_raise_twice(): +def DONOTtest_call_raise_twice(): res = interpret(call_raise_twice, [6, 7]) assert res == 13 info = raises(LLException, interpret, call_raise_twice, [6, 42]) @@ -132,7 +103,7 @@ info = raises(LLException, interpret, call_raise_twice, [43, 7]) assert find_exception(info.value) is ValueError -def test_call_raise_intercept(): +def DONOTtest_call_raise_intercept(): res = interpret(call_raise_intercept, [41], view=False) assert res == 41 res = interpret(call_raise_intercept, [42]) @@ -250,7 +221,7 @@ res = interpret(f,[]) assert len(res.items) == 3 -def test_obj_obj_add(): +def DONOTtest_obj_obj_add(): def f(x,y): return x+y _1L = pyobjectptr(1L) @@ -258,7 +229,7 @@ res = interpret(f, [_1L, _2L], someobjects=True) assert res._obj.value == 3L -def test_ovf(): +def DONOTtest_ovf(): import sys def f(x): try: @@ -279,7 +250,7 @@ res = interpret(g, [-15]) assert res == 15 -def test_div_ovf_zer(): +def DONOTtest_div_ovf_zer(): import sys def f(x): try: @@ -295,7 +266,7 @@ res = interpret(f, [30]) assert res == (-sys.maxint - 1) // 30 -def test_mod_ovf_zer(): +def DONOTtest_mod_ovf_zer(): import sys def f(x): try: @@ -312,7 +283,7 @@ assert res == (-sys.maxint - 1) % 30 -def test_obj_obj_is(): +def DONOTtest_obj_obj_is(): def f(x,y): return x is y o = pyobjectptr(object()) From cfbolz at codespeak.net Sat Aug 6 17:55:28 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 6 Aug 2005 17:55:28 +0200 (CEST) Subject: [pypy-svn] r15741 - pypy/dist/pypy/rpython/memory Message-ID: <20050806155528.ABEBE27B55@code1.codespeak.net> Author: cfbolz Date: Sat Aug 6 17:55:27 2005 New Revision: 15741 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py Log: damn. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Sat Aug 6 17:55:27 2005 @@ -1,4 +1,3 @@ -import autopath from pypy.rpython.memory import lladdress from pypy.rpython.memory.lltypesimulation import simulatorptr, get_total_size from pypy.rpython.memory.lltypesimulation import get_fixed_size From arigo at codespeak.net Sat Aug 6 18:43:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Aug 2005 18:43:18 +0200 (CEST) Subject: [pypy-svn] r15742 - pypy/dist/pypy/rpython/test Message-ID: <20050806164318.DB5ED27B51@code1.codespeak.net> Author: arigo Date: Sat Aug 6 18:43:18 2005 New Revision: 15742 Modified: pypy/dist/pypy/rpython/test/test_remptydict.py Log: Checked in a test with 'view=True' again. Modified: pypy/dist/pypy/rpython/test/test_remptydict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_remptydict.py (original) +++ pypy/dist/pypy/rpython/test/test_remptydict.py Sat Aug 6 18:43:18 2005 @@ -9,5 +9,5 @@ def func(): a.d2 = {} return bool(a.d1) or bool(a.d2) - res = interpret(func, [], view=True) + res = interpret(func, []) assert res is False From arigo at codespeak.net Sat Aug 6 18:52:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 6 Aug 2005 18:52:46 +0200 (CEST) Subject: [pypy-svn] r15743 - in pypy/dist/pypy: objspace/std rpython rpython/test Message-ID: <20050806165246.A7F1827B51@code1.codespeak.net> Author: arigo Date: Sat Aug 6 18:52:41 2005 New Revision: 15743 Modified: pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: Another rtyper_makekey() bug... This time, built-in methods could get attached to the wrong (previously seen) s_self. The symptom, seen by Christian, is that depending on block ordering and given that '' and 'xx' have the same repr, the rtyper confuses ''.join() and 'xx'.join(). Fix: use directly the s_self in the rtyper_makekey(). This uses the fact that we hash SomeObjects by id. --This line, and those below, will be ignored-- M pypy/rpython/test/test_rbuiltin.py M pypy/rpython/rbuiltin.py M pypy/objspace/std/stringobject.py Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sat Aug 6 18:52:41 2005 @@ -971,9 +971,6 @@ except (MemoryError,OverflowError,ValueError): # ugh. ValueError is what you get on 64-bit machines for # integers in range(2**31, 2**63). - # XXX needed to initialize buffer for rtyper. Strange, - # because it's need seems to vary! - buffer = [' '] raise OperationError( space.w_OverflowError, space.wrap("repeated string is too long: %d %d" % (input_len,mul) )) pos = 0 Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Sat Aug 6 18:52:41 2005 @@ -33,7 +33,15 @@ return self.__class__, getattr(self, 'const', None) else: # built-in method case - return (self.__class__, self.methodname, self.s_self.rtyper_makekey()) + # NOTE: we hash by id of self.s_self here. This appears to be + # necessary because it ends up in hop.args_s[0] in the method call, + # and there is no telling what information the called + # rtype_method_xxx() will read from that hop.args_s[0]. + # See test_method_join in test_rbuiltin. + # There is no problem with self.s_self being garbage-collected and + # its id reused, because the BuiltinMethodRepr keeps a reference + # to it. + return (self.__class__, self.methodname, id(self.s_self)) class BuiltinFunctionRepr(Repr): Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Sat Aug 6 18:52:41 2005 @@ -216,3 +216,15 @@ return we_are_translated() res = interpret(f, []) assert res is True and f() is False + +def test_method_join(): + # this is tuned to catch a specific bug: + # a wrong rtyper_makekey() for BuiltinMethodRepr + def f(): + lst1 = ['abc', 'def'] + s1 = ', '.join(lst1) + lst2 = ['1', '2', '3'] + s2 = ''.join(lst2) + return s1 + s2 + res = interpret(f, []) + assert ''.join(list(res.chars)) == 'abc, def123' From nik at codespeak.net Sun Aug 7 17:53:12 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sun, 7 Aug 2005 17:53:12 +0200 (CEST) Subject: [pypy-svn] r15747 - pypy/dist/pypy/module/_sre Message-ID: <20050807155312.D53B427B51@code1.codespeak.net> Author: nik Date: Sun Aug 7 17:53:11 2005 New Revision: 15747 Modified: pypy/dist/pypy/module/_sre/app_sre.py Log: several optimizations Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Sun Aug 7 17:53:11 2005 @@ -357,7 +357,15 @@ self.repeat = None def match(self, pattern_codes): - # XXX INFO optimization missing here + # Optimization: Check string length. pattern_codes[3] contains the + # minimum length for a string to possibly match. + from sre_constants import OPCODES + if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: + if self.end - self.string_position < pattern_codes[3]: + #_log("reject (got %d chars, need %d)" + # % (self.end - self.string_position, pattern_codes[3])) + return False + dispatcher = _OpcodeDispatcher() self.context_stack.append(_MatchContext(self, pattern_codes)) has_matched = None @@ -369,10 +377,13 @@ return has_matched def search(self, pattern_codes): - from sre_constants import OPCODES + from sre_constants import OPCODES, SRE_INFO_PREFIX if pattern_codes[0] == OPCODES["info"]: - pattern_codes = pattern_codes[pattern_codes[1] + 1:] - # XXX USE_FAST_SEARCH optimizations missing here + # optimization info block + # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> + if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: + return self.fast_search(pattern_codes) + pattern_codes = pattern_codes[pattern_codes[1] + 1:] # XXX literal and charset optimizations missing here string_position = self.start while string_position <= self.end: @@ -383,6 +394,43 @@ string_position += 1 return False + def fast_search(self, pattern_codes): + """Skips forward in a string as fast as possible using information from + an optimization info block.""" + from sre_constants import SRE_INFO_LITERAL + # pattern starts with a known prefix + # <5=length> <6=skip> <7=prefix data> + flags = pattern_codes[2] + prefix_len = pattern_codes[5] + prefix_skip = pattern_codes[6] # don't really know what this is good for + prefix = pattern_codes[7:7 + prefix_len] + overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + i = 0 + string_position = self.string_position + while string_position < self.end: + while True: + if ord(self.string[string_position]) != prefix[i]: + if i == 0: + break + else: + i = overlap[i] + else: + i += 1 + if i == prefix_len: + # found a potential match + self.start = string_position + 1 - prefix_len + self.string_position = string_position + 1 \ + - prefix_len + prefix_skip + if flags & SRE_INFO_LITERAL: + return True # matched all of pure literal pattern + if self.match(pattern_codes[2 * prefix_skip:]): + return True + i = overlap[i] + break + string_position += 1 + return False + def set_mark(self, mark_nr, position): if mark_nr & 1: # This id marks the end of a group. @@ -683,18 +731,22 @@ # alternation # <0=skip> code ... #self._log(ctx, "BRANCH") + from sre_constants import OPCODES ctx.state.marks_push() ctx.skip_code(1) current_branch_length = ctx.peek_code(0) while current_branch_length: - # XXX OP_LITERAL and OP_IN optimizations here - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(1) - yield False - if child_context.has_matched: - ctx.has_matched = True - yield True - ctx.state.marks_pop_keep() + # The following tries to shortcut branches starting with a + # (unmatched) literal. _sre.c also shortcuts charsets here. + if not (ctx.peek_code(1) == OPCODES["literal"] and \ + (ctx.at_end() or ctx.peek_code(2) != ord(ctx.peek_char()))): + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.state.marks_pop_keep() ctx.skip_code(current_branch_length) current_branch_length = ctx.peek_code(0) ctx.state.marks_pop_discard() From ericvrp at codespeak.net Sun Aug 7 18:23:25 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sun, 7 Aug 2005 18:23:25 +0200 (CEST) Subject: [pypy-svn] r15748 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050807162325.0440127B55@code1.codespeak.net> Author: ericvrp Date: Sun Aug 7 18:23:24 2005 New Revision: 15748 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: - Added int_neg_ovf and int_abs_ovf (need to look into why supplied tests not generating these operands) - Refactored codewriter and genllvm to directly generate a llvm-sourcefile (was using an in-memory copy that just takes up valuable memory) Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Sun Aug 7 18:23:24 2005 @@ -3,17 +3,19 @@ from pypy.translator.llvm2.log import log log = log.codewriter -show_line_numbers = False # True -count = count().next class CodeWriter(object): - def __init__(self): - self._lines = [] + def __init__(self, f, show_line_number=False): + self.f = f + self.show_line_numbers = show_line_number + self.n_lines = 0 + self.count = count().next def append(self, line): - if show_line_numbers: - line = "%-75s; %d" % (line, len(self._lines) + 1) - self._lines.append(line) + self.n_lines += 1 + if self.show_line_numbers: + line = "%-75s; %d" % (line, self.n_lines) + print >> self.f, line def comment(self, line, indent=True): line = ";; " + line @@ -120,7 +122,7 @@ "%(fromvar)s to %(targettype)s" % locals()) def malloc(self, targetvar, type_, size=1, atomic=False): - cnt = count() + cnt = self.count() postfix = ('', '_atomic')[atomic] self.indent("%%malloc.Size.%(cnt)d = getelementptr %(type_)s* null, uint %(size)s" % locals()) self.indent("%%malloc.SizeU.%(cnt)d = cast %(type_)s* %%malloc.Size.%(cnt)d to uint" % locals()) @@ -145,5 +147,5 @@ res = res % (tmpname, len, tmpname) self.indent(res) - def __str__(self): - return "\n".join(self._lines) + #def __str__(self): + # return "\n".join(self._lines) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Sun Aug 7 18:23:24 2005 @@ -36,7 +36,7 @@ # for debug we create comments of every operation that may be executed self.debug = debug - def compile(self, func=None): + def gen_llvm_source(self, func=None): if func is None: func = self.translator.entrypoint self.entrypoint = func @@ -55,10 +55,21 @@ assert c in self.db.obj2node self.db.setup_all() - log.compile(self.db.dump_pbcs()) + if self.debug: + log.gen_llvm_source(self.db.dump_pbcs()) self.entrynode = self.db.obj2node[c] - codewriter = CodeWriter() + + # prevent running the same function twice in a test + if func.func_name in function_count: + postfix = '_%d' % function_count[func.func_name] + function_count[func.func_name] += 1 + else: + postfix = '' + function_count[func.func_name] = 1 + filename = udir.join(func.func_name + postfix).new(ext='.ll') + + codewriter = CodeWriter( open(str(filename),'w') ) comment = codewriter.comment nl = codewriter.newline @@ -141,39 +152,26 @@ codewriter.newline() comment("End of file") ; nl() - self.content = str(codewriter) - return self.content - - def create_module(self, exe_name=None): - # hack to prevent running the same function twice in a test - func = self.entrypoint - if func.func_name in function_count: - postfix = '_%d' % function_count[func.func_name] - function_count[func.func_name] += 1 - else: - postfix = '' - - function_count[func.func_name] = 1 - - targetdir = udir - llvmsource = targetdir.join(func.func_name+postfix).new(ext='.ll') - llvmsource.write(self.content) # XXX writing to disc directly would conserve memory + return filename + def create_module(self, filename, exe_name=None): if not llvm_is_on_path(): py.test.skip("llvm not found") # XXX not good to call py.test.skip here - pyxsource = llvmsource.new(basename=llvmsource.purebasename+'_wrapper'+postfix+'.pyx') + postfix = '' + pyxsource = filename.new(basename=filename.purebasename+'_wrapper'+postfix+'.pyx') write_pyx_wrapper(self.entrynode, pyxsource) - return build_llvm_module.make_module_from_llvm(llvmsource, pyxsource, exe_name=exe_name) + return build_llvm_module.make_module_from_llvm(filename, pyxsource, exe_name=exe_name) def _debug_prototype(self, codewriter): codewriter.append("declare int %printf(sbyte*, ...)") def genllvm(translator, embedexterns=True, exe_name=None): gen = GenLLVM(translator, embedexterns=embedexterns) - log.genllvm(gen.compile()) - return gen.create_module(exe_name) + filename = gen.gen_llvm_source() + #log.genllvm(open(filename).read()) + return gen.create_module(filename, exe_name) def llvm_is_on_path(): try: @@ -182,19 +180,19 @@ return False return True -def compile_module(function, annotate, view=False, embedexterns=True, exe_name=None): +def compile_module(function, annotation, view=False, embedexterns=True, exe_name=None): t = Translator(function) - a = t.annotate(annotate) + a = t.annotate(annotation) t.specialize() if view: t.view() return genllvm(t, embedexterns=embedexterns, exe_name=exe_name) -def compile_function(function, annotate, view=False, embedexterns=True, exe_name=None): - mod = compile_module(function, annotate, view, embedexterns=embedexterns, exe_name=exe_name) +def compile_function(function, annotation, view=False, embedexterns=True, exe_name=None): + mod = compile_module(function, annotation, view, embedexterns=embedexterns, exe_name=exe_name) return getattr(mod, function.func_name + "_wrapper") -def compile_module_function(function, annotate, view=False, embedexterns=True, exe_name=None): - mod = compile_module(function, annotate, view, embedexterns=embedexterns, exe_name=exe_name) +def compile_module_function(function, annotation, view=False, embedexterns=True, exe_name=None): + mod = compile_module(function, annotation, view, embedexterns=embedexterns, exe_name=exe_name) f = getattr(mod, function.func_name + "_wrapper") return mod, f Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Sun Aug 7 18:23:24 2005 @@ -24,7 +24,9 @@ """) -for exc in "ZeroDivisionError OverflowError ValueError".split(): + +#prepage exceptions +for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ fastcc void %%__prepare_%(exc)s() { %%exception_value = call fastcc %%structtype.object* %%instantiate_%(exc)s() @@ -37,23 +39,104 @@ """ % locals()) + +#binary with ZeroDivisionError only for func_inst in "floordiv_zer:div mod_zer:rem".split(): func, inst = func_inst.split(':') for type_ in "int uint".split(): extfunctions["%%%(type_)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { + + ;zerodiv test %%cond = seteq %(type_)s %%y, 0 br bool %%cond, label %%is_0, label %%is_not_0 +is_0: + call fastcc void %%__prepare_ZeroDivisionError() + unwind + is_not_0: %%z = %(inst)s %(type_)s %%x, %%y ret %(type_)s %%z -is_0: - call fastcc void %%__prepare_ZeroDivisionError() +} + +""" % locals()) + + +ovf_test = """ + ;overflow test + %%cond2 = setge int %%x2, 0 + br bool %%cond2, label %%return_block, label %%block2 +block2: + %%tmp = sub int 0, %%x2 + %%cond3 = setne int %%x2, %%tmp + br bool %%cond3, label %%return_block, label %%ovf +ovf: + call fastcc void %%__prepare_OverflowError() unwind + +""" + +#unary with OverflowError only + +extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """ +fastcc int %%int_neg_ovf(int %%x) { +block1: + %%x2 = sub int 0, %%x + %(ovf_test)s +return_block: + ret int %%x2 +} + +""" % locals()) + +extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """ +fastcc int %%int_abs_ovf(int %%x) { +block0: + %%cond1 = setge int %%x, 0 + br bool %%cond1, label %%return_block, label %%is_negative +block1: + %%x2 = sub int 0, %%x + %(ovf_test)s +return_block: + %%result = phi int [%%x, %%block0], [%%x2, %%block1], [%%x2, %%block2] + ret int %%result } """ % locals()) + #XXX TODO -#src/int.h:#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \ -#src/int.h:#define OP_INT_MOD_OVF_ZER(x,y,r,err) + +#overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) ok else _OVF() + +#binary with overflow +#define OP_INT_ADD_OVF(x,y,r,err) \ +#define OP_INT_SUB_OVF(x,y,r,err) \ +#define OP_INT_MUL_OVF(x,y,r,err) \ +#define OP_INT_MUL_OVF(x,y,r,err) \ +#define OP_INT_FLOORDIV_OVF(x,y,r,err) \ +#define OP_INT_MOD_OVF(x,y,r,err) \ + +#binary with overflow and zerodiv +#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \ +#define OP_INT_MOD_OVF_ZER(x,y,r,err) \ + +#shift +#define OP_INT_LSHIFT_OVF(x,y,r,err) \ +#define OP_INT_LSHIFT_OVF_VAL(x,y,r,err) \ +#define OP_INT_RSHIFT_VAL(x,y,r,err) \ +#define OP_INT_LSHIFT_VAL(x,y,r,err) \ + + +#DONE + +#binary with zerodivisionerror only +#define OP_INT_FLOORDIV_ZER(x,y,r,err) \ +#define OP_UINT_FLOORDIV_ZER(x,y,r,err) \ +#define OP_INT_MOD_ZER(x,y,r,err) \ +#define OP_UINT_MOD_ZER(x,y,r,err) \ + +#unary with overflow only +#define OP_INT_ABS_OVF(x,r,err) \ untested +#define OP_INT_NEG_OVF(x,r,err) \ untested + Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Sun Aug 7 18:23:24 2005 @@ -4,6 +4,8 @@ from pypy.translator.test.snippet import try_raise_choose from pypy.rpython.rarithmetic import r_uint +import sys + class TestException(Exception): pass @@ -136,6 +138,30 @@ for i in (0,50,100): assert f(i) == zerodivrem_uint(i) +def test_neg_int_ovf(): + py.test.skip("When does int_neg_ovf get generated") + def neg_int_ovf(n): + try: + r=-n + except OverflowError: + return 123 + return r + f = compile_function(neg_int_ovf, [int]) + for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): + assert f(i) == neg_int_ovf(i) + +def test_abs_int_ovf(): + py.test.skip("When does int_abs_ovf get generated") + def abs_int_ovf(n): + try: + r=abs(n) + except OverflowError: + return 123 + return r + f = compile_function(abs_int_ovf, [int], True) + for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): + assert f(i) == abs_int_ovf(i) + def test_reraise1(): def fn(n): lst = range(10) From arigo at codespeak.net Sun Aug 7 22:47:37 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 7 Aug 2005 22:47:37 +0200 (CEST) Subject: [pypy-svn] r15751 - pypy/dist/pypy/module/_sre Message-ID: <20050807204737.9BBD327B51@code1.codespeak.net> Author: arigo Date: Sun Aug 7 22:47:35 2005 New Revision: 15751 Modified: pypy/dist/pypy/module/_sre/__init__.py Log: Typo. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Sun Aug 7 22:47:35 2005 @@ -6,7 +6,7 @@ '__name__': 'app_sre.__name__', '__doc__': 'app_sre.__doc__', 'CODESIZE': 'app_sre.CODESIZE', - 'MAGIC': 'app_sre.CODESIZE', + 'MAGIC': 'app_sre.MAGIC', 'copyright': 'app_sre.copyright', 'compile': 'app_sre.compile', 'getcodesize': 'app_sre.getcodesize', From arigo at codespeak.net Sun Aug 7 23:07:52 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 7 Aug 2005 23:07:52 +0200 (CEST) Subject: [pypy-svn] r15752 - in pypy/dist/pypy/module: _sre array Message-ID: <20050807210752.EF6BC27B51@code1.codespeak.net> Author: arigo Date: Sun Aug 7 23:07:49 2005 New Revision: 15752 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/array/app_array.py Log: * minor: give _sre.MAGIC the value of Python 2.4 on future versions (> 2.4) as well * XXX missing slice deletion in class 'array'. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Sun Aug 7 23:07:49 2005 @@ -15,7 +15,7 @@ #from sre_constants import ATCODES, OPCODES, CHCODES, MAXREPEAT # Identifying as _sre from Python 2.3 or 2.4 -if sys.version_info[:2] == (2, 4): +if sys.version_info[:2] >= (2, 4): MAGIC = 20031017 else: MAGIC = 20030419 Modified: pypy/dist/pypy/module/array/app_array.py ============================================================================== --- pypy/dist/pypy/module/array/app_array.py (original) +++ pypy/dist/pypy/module/array/app_array.py Sun Aug 7 23:07:49 2005 @@ -444,6 +444,7 @@ self.__setitem__(slice(i, j), x) def __delitem__(self, i): + # XXX missing: deleting a slice del self._data[i] def __delslice__(self, i, j): From arigo at codespeak.net Sun Aug 7 23:18:31 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 7 Aug 2005 23:18:31 +0200 (CEST) Subject: [pypy-svn] r15753 - pypy/dist/pypy/interpreter Message-ID: <20050807211831.E28A427B46@code1.codespeak.net> Author: arigo Date: Sun Aug 7 23:18:29 2005 New Revision: 15753 Modified: pypy/dist/pypy/interpreter/mixedmodule.py Log: Use the docstring of the MixedModule subclass as exported __doc__, if nothing else is available. Modified: pypy/dist/pypy/interpreter/mixedmodule.py ============================================================================== --- pypy/dist/pypy/interpreter/mixedmodule.py (original) +++ pypy/dist/pypy/interpreter/mixedmodule.py Sun Aug 7 23:18:29 2005 @@ -85,6 +85,8 @@ loaders[name] = getappfileloader(pkgroot, spec) assert '__file__' not in loaders loaders['__file__'] = cls.get__file__ + if '__doc__' not in loaders: + loaders['__doc__'] = cls.get__doc__ buildloaders = classmethod(buildloaders) @@ -107,6 +109,10 @@ get__file__ = classmethod(get__file__) + def get__doc__(cls, space): + return space.wrap(cls.__doc__) + get__doc__ = classmethod(get__doc__) + def getinterpevalloader(pkgroot, spec): """ NOT_RPYTHON """ From arigo at codespeak.net Sun Aug 7 23:31:03 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 7 Aug 2005 23:31:03 +0200 (CEST) Subject: [pypy-svn] r15754 - pypy/dist/pypy/module/_sre Message-ID: <20050807213103.1459E27B46@code1.codespeak.net> Author: arigo Date: Sun Aug 7 23:30:59 2005 New Revision: 15754 Added: pypy/dist/pypy/module/_sre/app_info.py (contents, props changed) Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py Log: Split app_sre.py in two files: the magic constants are now in app_info.py. This scheme allows us to get rid of the circular import dependency between app_sre.py and sre_constants.py. More generally, as long as user code only wants to check the _sre.MAGIC or CODESIZE constants, app_sre.py doesn't have to be imported. This change can be discussed -- it means that app_sre.py becomes (slightly) different than http://codespeak.net/svn/user/nik/_sre_py/trunk/src/_sre.py. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Sun Aug 7 23:30:59 2005 @@ -1,15 +1,19 @@ from pypy.interpreter.mixedmodule import MixedModule class Module(MixedModule): + """A pure Python reimplementation of the _sre module from CPython 2.4 +Copyright 2005 Nik Haldimann, licensed under the MIT license + +This code is based on material licensed under CNRI's Python 1.6 license and +copyrighted by: Copyright (c) 1997-2001 by Secret Labs AB +""" appleveldefs = { - '__name__': 'app_sre.__name__', - '__doc__': 'app_sre.__doc__', - 'CODESIZE': 'app_sre.CODESIZE', - 'MAGIC': 'app_sre.MAGIC', - 'copyright': 'app_sre.copyright', + 'CODESIZE': 'app_info.CODESIZE', + 'MAGIC': 'app_info.MAGIC', + 'copyright': 'app_info.copyright', + 'getcodesize': 'app_info.getcodesize', 'compile': 'app_sre.compile', - 'getcodesize': 'app_sre.getcodesize', 'getlower': 'app_sre.getlower', } Added: pypy/dist/pypy/module/_sre/app_info.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/app_info.py Sun Aug 7 23:30:59 2005 @@ -0,0 +1,30 @@ +# NOT_RPYTHON (no point unless app_sre.py is made RPython too) + +# Constants and magic numbers for app_sre.py. +# Moving these values in a separate file allows app_sre.py not to be loaded +# by app-level code that just inspects the _sre magic numbers. + +import sys + +# Identifying as _sre from Python 2.3 or 2.4 +if sys.version_info[:2] >= (2, 4): + MAGIC = 20031017 +else: + MAGIC = 20030419 + +# In _sre.c this is bytesize of the code word type of the C implementation. +# There it's 2 for normal Python builds and more for wide unicode builds (large +# enough to hold a 32-bit UCS-4 encoded character). Since here in pure Python +# we only see re bytecodes as Python longs, we shouldn't have to care about the +# codesize. But sre_compile will compile some stuff differently depending on the +# codesize (e.g., charsets). +if sys.maxunicode == 65535: + CODESIZE = 2 +else: + CODESIZE = 4 + +copyright = "_sre.py 2.4a Copyright 2005 by Nik Haldimann" + + +def getcodesize(): + return CODESIZE Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Sun Aug 7 23:30:59 2005 @@ -8,34 +8,11 @@ """ import array, operator, sys -# XXX Avoiding sre_constants import on module level to cater for a hack in -# sre_constants concerned with _sre faking on 2.3. Fix this when _sre faking is -# not an issue anymore. -#import sre_constants -#from sre_constants import ATCODES, OPCODES, CHCODES, MAXREPEAT - -# Identifying as _sre from Python 2.3 or 2.4 -if sys.version_info[:2] >= (2, 4): - MAGIC = 20031017 -else: - MAGIC = 20030419 - -# In _sre.c this is bytesize of the code word type of the C implementation. -# There it's 2 for normal Python builds and more for wide unicode builds (large -# enough to hold a 32-bit UCS-4 encoded character). Since here in pure Python -# we only see re bytecodes as Python longs, we shouldn't have to care about the -# codesize. But sre_compile will compile some stuff differently depending on the -# codesize (e.g., charsets). -if sys.maxunicode == 65535: - CODESIZE = 2 -else: - CODESIZE = 4 +import sre_constants +from sre_constants import ATCODES, OPCODES, CHCODES, MAXREPEAT +from sre_constants import SRE_INFO_PREFIX, SRE_INFO_LITERAL +from _sre import CODESIZE -copyright = "_sre.py 2.4a Copyright 2005 by Nik Haldimann" - - -def getcodesize(): - return CODESIZE def compile(pattern, flags, code, groups=0, groupindex={}, indexgroup=[None]): """Compiles (or rather just converts) a pattern descriptor to a SRE_Pattern @@ -43,7 +20,6 @@ return SRE_Pattern(pattern, flags, code, groups, groupindex, indexgroup) def getlower(char_ord, flags): - import sre_constants if (char_ord < 128) or (flags & sre_constants.SRE_FLAG_UNICODE) \ or (flags & sre_constants.SRE_FLAG_LOCALE and char_ord < 256): return ord(unichr(char_ord).lower()) @@ -359,7 +335,6 @@ def match(self, pattern_codes): # Optimization: Check string length. pattern_codes[3] contains the # minimum length for a string to possibly match. - from sre_constants import OPCODES if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: if self.end - self.string_position < pattern_codes[3]: #_log("reject (got %d chars, need %d)" @@ -377,7 +352,6 @@ return has_matched def search(self, pattern_codes): - from sre_constants import OPCODES, SRE_INFO_PREFIX if pattern_codes[0] == OPCODES["info"]: # optimization info block # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> @@ -397,7 +371,6 @@ def fast_search(self, pattern_codes): """Skips forward in a string as fast as possible using information from an optimization info block.""" - from sre_constants import SRE_INFO_LITERAL # pattern starts with a known prefix # <5=length> <6=skip> <7=prefix data> flags = pattern_codes[2] @@ -552,7 +525,6 @@ def __init__(self): self.executing_contexts = {} - from sre_constants import ATCODES, OPCODES, CHCODES _OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") _AtcodeDispatcher.build_dispatch_table(ATCODES, "") _ChcodeDispatcher.build_dispatch_table(CHCODES, "") @@ -731,7 +703,6 @@ # alternation # <0=skip> code ... #self._log(ctx, "BRANCH") - from sre_constants import OPCODES ctx.state.marks_push() ctx.skip_code(1) current_branch_length = ctx.peek_code(0) @@ -758,7 +729,6 @@ # this operator only works if the repeated item is exactly one character # wide, and we're not already collecting backtracking points. # <1=min> <2=max> item tail - from sre_constants import OPCODES mincount = ctx.peek_code(2) maxcount = ctx.peek_code(3) #self._log(ctx, "REPEAT_ONE", mincount, maxcount) @@ -800,7 +770,6 @@ def op_min_repeat_one(self, ctx): # match repeated sequence (minimizing) # <1=min> <2=max> item tail - from sre_constants import OPCODES, MAXREPEAT mincount = ctx.peek_code(2) maxcount = ctx.peek_code(3) #self._log(ctx, "MIN_REPEAT_ONE", mincount, maxcount) @@ -859,7 +828,6 @@ def op_max_until(self, ctx): # maximizing repeat # <1=min> <2=max> item tail - from sre_constants import MAXREPEAT repeat = ctx.state.repeat if repeat is None: raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") @@ -911,7 +879,6 @@ def op_min_until(self, ctx): # minimizing repeat # <1=min> <2=max> item tail - from sre_constants import MAXREPEAT repeat = ctx.state.repeat if repeat is None: raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") @@ -1043,7 +1010,6 @@ """Returns the number of repetitions of a single item, starting from the current string position. The code pointer is expected to point to a REPEAT_ONE operation (with the repeated 4 ahead).""" - from sre_constants import MAXREPEAT count = 0 real_maxcount = ctx.state.end - ctx.string_position if maxcount < real_maxcount and maxcount != MAXREPEAT: From arigo at codespeak.net Sun Aug 7 23:47:05 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 7 Aug 2005 23:47:05 +0200 (CEST) Subject: [pypy-svn] r15755 - pypy/dist/pypy/module/array Message-ID: <20050807214705.DF57C27B4E@code1.codespeak.net> Author: arigo Date: Sun Aug 7 23:47:03 2005 New Revision: 15755 Added: pypy/dist/pypy/module/array/ - copied from r15751, pypy/dist/pypy/module/array/ Log: Reverted erroneous XXX. Slice deletion works just fine, sorry. From cfbolz at codespeak.net Mon Aug 8 11:46:50 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 11:46:50 +0200 (CEST) Subject: [pypy-svn] r15760 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050808094650.598E727B42@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 11:46:49 2005 New Revision: 15760 Modified: pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: introduced a correct pyobjectptr implementation. Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Mon Aug 8 11:46:49 2005 @@ -8,6 +8,7 @@ from pypy.rpython.memory.lltypesimulation import cast_pointer from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr +from pypy.rpython.memory.lltypesimulation import pyobjectptr def notimplemented(*args, **kwargs): @@ -23,7 +24,7 @@ # opaqueptr, pyobjectptr, attachRuntimeTypeInfo, getRuntimeTypeInfo, # runtime_type_info -opaqueptr = pyobjectptr = attachRuntimeTypeInfo = notimplemented +opaqueptr = attachRuntimeTypeInfo = notimplemented getRuntimeTypeInfo = runtime_type_info = notimplemented del notimplemented Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Mon Aug 8 11:46:49 2005 @@ -254,6 +254,7 @@ def nullptr(T): return simulatorptr(lltype.Ptr(T), lladdress.NULL) +#XXX unify attached objects with the address space as to samuele's suggestion def functionptr(TYPE, name, **attrs): if not isinstance(TYPE, lltype.FuncType): raise TypeError, "functionptr() for FuncTypes only" @@ -264,3 +265,8 @@ addr = lladdress.raw_malloc(get_total_size(TYPE)) addr.attached[0] = lltype._func(TYPE, _name=name, **attrs) return simulatorptr(lltype.Ptr(TYPE), addr) + +def pyobjectptr(obj): + addr = lladdress.raw_malloc(get_total_size(lltype.PyObject)) + addr.attached[0] = lltype._pyobject(obj) + return simulatorptr(lltype.Ptr(lltype.PyObject), addr) Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Mon Aug 8 11:46:49 2005 @@ -1,6 +1,6 @@ import py -from pypy.rpython.lltype import typeOf, pyobjectptr, Ptr, PyObject +from pypy.rpython.lltype import typeOf, Ptr, PyObject from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.llinterp import LLInterpreter, LLException,log from pypy.translator.translator import Translator @@ -9,9 +9,10 @@ from pypy.rpython import rstr from pypy.annotation.model import lltype_to_annotation from pypy.rpython.rarithmetic import r_uint, ovfcheck +from pypy.rpython.memory.lltypesimulation import pyobjectptr from pypy.rpython.memory import gclltype -from pypy.rpython.test.test_llinterp import find_exception, timelog, gengraph +from pypy.rpython.test.test_llinterp import timelog, gengraph # switch on logging of interp to show more info on failing tests @@ -22,6 +23,7 @@ def teardown_module(mod): py.log._setstate(mod.logstate) + _lastinterpreted = [] _tcache = {} def interpret(func, values, view=False, viewbefore=False, policy=None, someobjects=False): @@ -221,7 +223,7 @@ res = interpret(f,[]) assert len(res.items) == 3 -def DONOTtest_obj_obj_add(): +def test_obj_obj_add(): def f(x,y): return x+y _1L = pyobjectptr(1L) @@ -283,7 +285,7 @@ assert res == (-sys.maxint - 1) % 30 -def DONOTtest_obj_obj_is(): +def test_obj_obj_is(): def f(x,y): return x is y o = pyobjectptr(object()) From cfbolz at codespeak.net Mon Aug 8 13:33:41 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 13:33:41 +0200 (CEST) Subject: [pypy-svn] r15762 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050808113341.5F15F27B48@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 13:33:40 2005 New Revision: 15762 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: moving toward fixing exception handling when using the simulated lltypes: had to do a slightly different exception matching. Still some problems with catching superclasses of the raised exception. Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Mon Aug 8 13:33:40 2005 @@ -92,6 +92,8 @@ return address._load(primitive_to_fmt[T])[0] elif isinstance(T, lltype.Ptr): return simulatorptr(T, address.address[0]) + elif isinstance(T, lltype.PyObjectType): + return simulatorptr(lltype.Ptr(T), address) else: assert 0, "not implemented yet" Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Mon Aug 8 13:33:40 2005 @@ -13,6 +13,7 @@ from pypy.rpython.memory import gclltype from pypy.rpython.test.test_llinterp import timelog, gengraph +from pypy.rpython.test import test_llinterp # switch on logging of interp to show more info on failing tests @@ -24,6 +25,18 @@ py.log._setstate(mod.logstate) +def find_exception(exc, interp): + assert isinstance(exc, LLException) + import exceptions + klass, inst = exc.args + func = test_llinterp.typer.getexceptiondata().ll_pyexcclass2exc + for cls in exceptions.__dict__.values(): + if type(cls) is type(Exception): + if interp.eval_function(func, [pyobjectptr(cls)]).typeptr == klass: + return cls + raise ValueError, "couldn't match exception" + + _lastinterpreted = [] _tcache = {} def interpret(func, values, view=False, viewbefore=False, policy=None, someobjects=False): @@ -53,6 +66,34 @@ t.view() return interp.eval_function(func, values) +def interpret_raises(exc, func, values, view=False, viewbefore=False, policy=None, someobjects=False): + key = (func,) + tuple([typeOf(x) for x in values])+ (someobjects,) + try: + (t, interp) = _tcache[key] + except KeyError: + def annotation(x): + T = typeOf(x) + if T == Ptr(PyObject) and someobjects: + return object + elif T == Ptr(rstr.STR): + return str + else: + return lltype_to_annotation(T) + + t, typer = gengraph(func, [annotation(x) + for x in values], viewbefore, policy) + interp = LLInterpreter(t.flowgraphs, typer, gclltype, + gclltype.prepare_graphs) + _tcache[key] = (t, interp) + # keep the cache small + _lastinterpreted.append(key) + if len(_lastinterpreted) >= 4: + del _tcache[_lastinterpreted.pop(0)] + if view: + t.view() + info = py.test.raises(LLException, "interp.eval_function(func, values)") + assert find_exception(info.value, interp) is exc, "wrong exception type" + #__________________________________________________________________ # tests @@ -77,41 +118,33 @@ res = interpret(simple_ifs, [1]) assert res == 42 -def DONOTtest_raise(): +def test_raise(): res = interpret(raise_exception, [41]) assert res == 41 - info = raises(LLException, interpret, raise_exception, [42]) - assert find_exception(info.value) is IndexError - info = raises(LLException, interpret, raise_exception, [43]) - assert find_exception(info.value) is ValueError + interpret_raises(IndexError, raise_exception, [42]) + interpret_raises(ValueError, raise_exception, [43]) -def DONOTtest_call_raise(): +def test_call_raise(): res = interpret(call_raise, [41]) assert res == 41 - info = raises(LLException, interpret, call_raise, [42]) - assert find_exception(info.value) is IndexError - info = raises(LLException, interpret, call_raise, [43]) - assert find_exception(info.value) is ValueError + interpret_raises(IndexError, call_raise, [42]) + interpret_raises(ValueError, call_raise, [43]) def DONOTtest_call_raise_twice(): res = interpret(call_raise_twice, [6, 7]) assert res == 13 - info = raises(LLException, interpret, call_raise_twice, [6, 42]) - assert find_exception(info.value) is IndexError + interpret_raises(IndexError, call_raise_twice, [6, 42]) res = interpret(call_raise_twice, [6, 43]) assert res == 1006 - info = raises(LLException, interpret, call_raise_twice, [42, 7]) - assert find_exception(info.value) is IndexError - info = raises(LLException, interpret, call_raise_twice, [43, 7]) - assert find_exception(info.value) is ValueError + interpret_raises(IndexError, call_raise_twice, [42, 7]) + interpret_raises(ValueError, call_raise_twice, [43, 7]) def DONOTtest_call_raise_intercept(): res = interpret(call_raise_intercept, [41], view=False) assert res == 41 res = interpret(call_raise_intercept, [42]) assert res == 42 - info = raises(LLException, interpret, call_raise_intercept, [43]) - assert find_exception(info.value) is TypeError + interpret_raises(TypeError, call_raise_intercept, [43]) def test_while_simple(): res = interpret(while_simple, [3]) @@ -231,7 +264,7 @@ res = interpret(f, [_1L, _2L], someobjects=True) assert res._obj.value == 3L -def DONOTtest_ovf(): +def test_ovf(): import sys def f(x): try: @@ -252,7 +285,7 @@ res = interpret(g, [-15]) assert res == 15 -def DONOTtest_div_ovf_zer(): +def test_div_ovf_zer(): import sys def f(x): try: @@ -268,7 +301,7 @@ res = interpret(f, [30]) assert res == (-sys.maxint - 1) // 30 -def DONOTtest_mod_ovf_zer(): +def test_mod_ovf_zer(): import sys def f(x): try: From nik at codespeak.net Mon Aug 8 13:44:12 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Mon, 8 Aug 2005 13:44:12 +0200 (CEST) Subject: [pypy-svn] r15763 - pypy/dist/pypy/module/_sre Message-ID: <20050808114412.067F527B42@code1.codespeak.net> Author: nik Date: Mon Aug 8 13:44:11 2005 New Revision: 15763 Modified: pypy/dist/pypy/module/_sre/app_sre.py Log: build dispatch tables only once, now that sre_constants import restrictions are gone. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Mon Aug 8 13:44:11 2005 @@ -8,9 +8,9 @@ """ import array, operator, sys -import sre_constants 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 from _sre import CODESIZE @@ -20,8 +20,8 @@ return SRE_Pattern(pattern, flags, code, groups, groupindex, indexgroup) def getlower(char_ord, flags): - if (char_ord < 128) or (flags & sre_constants.SRE_FLAG_UNICODE) \ - or (flags & sre_constants.SRE_FLAG_LOCALE and char_ord < 256): + if (char_ord < 128) or (flags & SRE_FLAG_UNICODE) \ + or (flags & SRE_FLAG_LOCALE and char_ord < 256): return ord(unichr(char_ord).lower()) else: return char_ord @@ -525,10 +525,6 @@ def __init__(self): self.executing_contexts = {} - _OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") - _AtcodeDispatcher.build_dispatch_table(ATCODES, "") - _ChcodeDispatcher.build_dispatch_table(CHCODES, "") - _CharsetDispatcher.build_dispatch_table(OPCODES, "set_") self.at_dispatcher = _AtcodeDispatcher() self.ch_dispatcher = _ChcodeDispatcher() self.set_dispatcher = _CharsetDispatcher() @@ -1039,6 +1035,8 @@ _log("|%s|%s|%s %s" % (context.pattern_codes, context.string_position, opname, arg_string)) +_OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") + class _CharsetDispatcher(_Dispatcher): @@ -1108,6 +1106,8 @@ def unknown(self, ctx): return False +_CharsetDispatcher.build_dispatch_table(OPCODES, "set_") + class _AtcodeDispatcher(_Dispatcher): @@ -1137,6 +1137,8 @@ def unknown(self, ctx): return False +_AtcodeDispatcher.build_dispatch_table(ATCODES, "") + class _ChcodeDispatcher(_Dispatcher): @@ -1179,6 +1181,8 @@ def unknown(self, ctx): return False +_ChcodeDispatcher.build_dispatch_table(CHCODES, "") + _ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, From cfbolz at codespeak.net Mon Aug 8 14:17:45 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 14:17:45 +0200 (CEST) Subject: [pypy-svn] r15765 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050808121745.5D32127B42@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 14:17:44 2005 New Revision: 15765 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: arggh!! did not define __ne__ for simulatorptr which leads to annoying bugs. Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Mon Aug 8 14:17:44 2005 @@ -213,6 +213,9 @@ def __nonzero__(self): return self._address != lladdress.NULL + def __ne__(self, other): + return not self.__eq__(other) + def __eq__(self, other): if not isinstance(other, simulatorptr): raise TypeError("comparing pointer with %r object" % ( Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Mon Aug 8 14:17:44 2005 @@ -305,3 +305,12 @@ F = lltype.FuncType((lltype.Signed, lltype.Signed), lltype.Signed) funcptr = functionptr(F, "add", _callable=f) assert funcptr(1, 2) == 3 + +def test_pointer_equality(): + S0 = lltype.GcStruct("s0", + ('a', lltype.Struct("s1", ('a', lltype.Signed))), + ('b', lltype.Signed)) + s0 = malloc(S0) + assert s0.a == s0.a + assert not s0.a != s0.a + From cfbolz at codespeak.net Mon Aug 8 14:29:19 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 14:29:19 +0200 (CEST) Subject: [pypy-svn] r15767 - pypy/dist/pypy/rpython/memory Message-ID: <20050808122919.3A7BA27B42@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 14:29:18 2005 New Revision: 15767 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py Log: need to convert link.llexitcase as well. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Mon Aug 8 14:29:18 2005 @@ -118,6 +118,7 @@ def visit(obj): if isinstance(obj, Link): collect_args(obj.args) + constants[Constant(obj.llexitcase)] = None elif isinstance(obj, Block): for op in obj.operations: collect_args(op.args) @@ -188,6 +189,8 @@ def visit(obj): if isinstance(obj, Link): patch_consts(obj.args) + if Constant(obj.llexitcase) in self.constants: + obj.llexitcase = self.constants[Constant(obj.llexitcase)] elif isinstance(obj, Block): for op in obj.operations: patch_consts(op.args) From cfbolz at codespeak.net Mon Aug 8 14:33:13 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 14:33:13 +0200 (CEST) Subject: [pypy-svn] r15768 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050808123313.5DE8927B42@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 14:33:12 2005 New Revision: 15768 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: changed the llinterpreter to not only call but actually interpret the exception matching functions to give the lltypesimulation a chance to succeed. now all tests in llinterpsim pass. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Aug 8 14:33:12 2005 @@ -167,7 +167,8 @@ cls, inst = e.args for link in block.exits[1:]: assert issubclass(link.exitcase, Exception) - if exdata.ll_exception_match(cls, link.llexitcase): + if self.llinterpreter.eval_function( + exdata.ll_exception_match, [cls, link.llexitcase]): self.setifvar(link.last_exception, cls) self.setifvar(link.last_exc_value, inst) break @@ -198,8 +199,10 @@ assert False, "op_direct_call above should have raised" else: exc_class = exc.__class__ - evalue = exdata.ll_pyexcclass2exc(self.llt.pyobjectptr(exc_class)) - etype = exdata.ll_type_of_exc_inst(evalue) + evalue = self.llinterpreter.eval_function( + exdata.ll_pyexcclass2exc, [self.llt.pyobjectptr(exc_class)]) + etype = self.llinterpreter.eval_function( + exdata.ll_type_of_exc_inst, [evalue]) raise LLException(etype, evalue) def invoke_callable_with_pyexceptions(self, fptr, *args): Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Mon Aug 8 14:33:12 2005 @@ -130,7 +130,7 @@ interpret_raises(IndexError, call_raise, [42]) interpret_raises(ValueError, call_raise, [43]) -def DONOTtest_call_raise_twice(): +def test_call_raise_twice(): res = interpret(call_raise_twice, [6, 7]) assert res == 13 interpret_raises(IndexError, call_raise_twice, [6, 42]) @@ -139,7 +139,7 @@ interpret_raises(IndexError, call_raise_twice, [42, 7]) interpret_raises(ValueError, call_raise_twice, [43, 7]) -def DONOTtest_call_raise_intercept(): +def test_call_raise_intercept(): res = interpret(call_raise_intercept, [41], view=False) assert res == 41 res = interpret(call_raise_intercept, [42]) From pedronis at codespeak.net Mon Aug 8 15:22:42 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 8 Aug 2005 15:22:42 +0200 (CEST) Subject: [pypy-svn] r15769 - in pypy/dist/pypy: module/_codecs translator translator/test Message-ID: <20050808132242.4E9C227B51@code1.codespeak.net> Author: pedronis Date: Mon Aug 8 15:22:36 2005 New Revision: 15769 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/translator/geninterplevel.py pypy/dist/pypy/translator/test/snippet.py pypy/dist/pypy/translator/test/test_geninterp.py Log: fixed support for isinstance|isubclass(., ) in geninterp recover original code intention in app_codecs n app_codecs? or is the long case not necessary??? Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Mon Aug 8 15:22:36 2005 @@ -1471,7 +1471,7 @@ def charmapencode_output(c,mapping): rep = mapping[c] - if isinstance(rep,int): + if isinstance(rep,int) or isinstance(rep, long): if rep<256: return chr(rep) else: Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Mon Aug 8 15:22:36 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.7' # bump this for substantial changes +GI_VERSION = '1.1.8' # bump this for substantial changes # ____________________________________________________________ try: @@ -225,9 +225,17 @@ return ", ".join(res) def oper(self, op, localscope): + if op.opname == 'issubtype': + arg = op.args[1] + if (not isinstance(arg, Constant) + or not isinstance(arg.value, (type, types.ClassType))): + op = SpaceOperation("simple_call", + [Constant(issubclass)]+op.args, + op.result) if op.opname == "simple_call": v = op.args[0] - space_shortcut = self.try_space_shortcut_for_builtin(v, len(op.args)-1) + space_shortcut = self.try_space_shortcut_for_builtin(v, len(op.args)-1, + op.args[1:]) if space_shortcut is not None: # space method call exv = space_shortcut @@ -658,12 +666,18 @@ arities['isinstance'] = 2 return self._space_arities - def try_space_shortcut_for_builtin(self, v, nargs): + 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 hasattr(self.space, name): if self.space_arities().get(name, -1) == nargs: - return "space.%s" % name + if name != 'isinstance': + return "space.%s" % name + else: + arg = args[1] + if (isinstance(arg, Constant) + and isinstance(arg.value, (type, types.ClassType))): + return "space.isinstance" return None def nameof_builtin_function_or_method(self, func): Modified: pypy/dist/pypy/translator/test/snippet.py ============================================================================== --- pypy/dist/pypy/translator/test/snippet.py (original) +++ pypy/dist/pypy/translator/test/snippet.py Mon Aug 8 15:22:36 2005 @@ -656,6 +656,16 @@ result += 1.0 / n return result + +# specifically for geninterp testing + +def t_isinstance(x, y): + return isinstance(x, (int, long)) and isinstance(y, int) + +def t_issubclass(x, y): + return issubclass(type(x), (int, long)) and issubclass(type(y), int) + + # --------------------(Currently) Non runnable Functions --------------------- def _somebug1(n=int): Modified: pypy/dist/pypy/translator/test/test_geninterp.py ============================================================================== --- pypy/dist/pypy/translator/test/test_geninterp.py (original) +++ pypy/dist/pypy/translator/test/test_geninterp.py Mon Aug 8 15:22:36 2005 @@ -251,3 +251,14 @@ fn = self.build_interpfunc(snippet.do_try_raise_choose) result = fn() assert result == [-1,0,1,2] + + + def test_t_isinstance(self): + fn = self.build_interpfunc(snippet.t_isinstance) + result = fn(1, 2) + assert result == True + + def test_t_issubclass(self): + fn = self.build_interpfunc(snippet.t_issubclass) + result = fn(1, 2) + assert result == True From cfbolz at codespeak.net Mon Aug 8 16:39:03 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 16:39:03 +0200 (CEST) Subject: [pypy-svn] r15770 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050808143903.E866B27B49@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 16:39:03 2005 New Revision: 15770 Added: pypy/dist/pypy/rpython/memory/test/__init__.py Log: adding __init__ file Added: pypy/dist/pypy/rpython/memory/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/test/__init__.py Mon Aug 8 16:39:03 2005 @@ -0,0 +1 @@ +# From pedronis at codespeak.net Mon Aug 8 16:48:03 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 8 Aug 2005 16:48:03 +0200 (CEST) Subject: [pypy-svn] r15771 - in pypy/dist/pypy/translator/c: . src Message-ID: <20050808144803.3A11227B49@code1.codespeak.net> Author: pedronis Date: Mon Aug 8 16:47:56 2005 New Revision: 15771 Modified: pypy/dist/pypy/translator/c/external.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/src/exception.h pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/src/ll_time.h pypy/dist/pypy/translator/c/src/mem.h pypy/dist/pypy/translator/c/src/support.h Log: issue107 in-progress use the prefixes: RPy/RPYTHON/rpython (and Py) consistently with our exception machinary: now we have RPyExceptionOccurred RPyRaiseException RPyFetchException RPyMatchException RPyConvertExceptionFromCPython RPyConvertExceptionToCPython RPyRaiseSimpleException RPyRaiseSimpleException is used as: RPyRaiseSimpleException(PyExc_IOError, "select() failed") and RPYTHON_RAISE_OSERROR Modified: pypy/dist/pypy/translator/c/external.py ============================================================================== --- pypy/dist/pypy/translator/c/external.py (original) +++ pypy/dist/pypy/translator/c/external.py Mon Aug 8 16:47:56 2005 @@ -28,8 +28,8 @@ call = '%s(%s)' % (self.fnptr._name, ', '.join(self.argnames())) if self.FUNCTYPE.RESULT != Void: yield 'result = %s;' % call - yield 'if (PyErr_Occurred()) ConvertExceptionFromCPython();' + yield 'if (PyErr_Occurred()) RPyConvertExceptionFromCPython();' yield 'return result;' else: yield '%s;' % call - yield 'if (PyErr_Occurred()) ConvertExceptionFromCPython();' + yield 'if (PyErr_Occurred()) RPyConvertExceptionFromCPython();' Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Mon Aug 8 16:47:56 2005 @@ -99,7 +99,7 @@ yield ('RPYTHON_EXCEPTION_MATCH', exceptiondata.ll_exception_match) yield ('RPYTHON_TYPE_OF_EXC_INST', exceptiondata.ll_type_of_exc_inst) - yield ('RAISE_OSERROR', exceptiondata.ll_raise_OSError) + yield ('RPYTHON_RAISE_OSERROR', exceptiondata.ll_raise_OSError) if not db.standalone: yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.ll_pyexcclass2exc) @@ -108,7 +108,7 @@ lltype.pyobjectptr(pyexccls)) # strange naming here because the macro name must be # a substring of PyExc_%s - yield ('Exc_%s' % pyexccls.__name__, exc_llvalue) + yield ('RPyExc_%s' % pyexccls.__name__, exc_llvalue) def predeclare_all(db, rtyper): Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Mon Aug 8 16:47:56 2005 @@ -104,7 +104,7 @@ assert self.lltypemap(self.graph.getreturnvar()) == PyObjPtr yield '{' yield '\t%s;' % cdecl(exc_value_typename, 'vanishing_exc_value') - yield '\tConvertExceptionToCPython(vanishing_exc_value);' + yield '\tRPyConvertExceptionToCPython(vanishing_exc_value);' yield '\t%s' % self.db.cdecrefstmt('vanishing_exc_value', lltype_of_exception_value) yield '}' yield 'return %s; ' % self.error_return_value() @@ -257,10 +257,10 @@ T2 = link.last_exc_value.concretetype typ1 = self.db.gettype(T1) typ2 = self.db.gettype(T2) - yield 'if (MatchException(%s)) {' % (self.db.get(etype),) + yield 'if (RPyMatchException(%s)) {' % (self.db.get(etype),) yield '\t%s;' % cdecl(typ1, 'exc_cls') yield '\t%s;' % cdecl(typ2, 'exc_value') - yield '\tFetchException(exc_cls, exc_value, %s);' % ( + yield '\tRPyFetchException(exc_cls, exc_value, %s);' % ( cdecl(typ2, '')) d = {} if isinstance(link.last_exception, Variable): @@ -362,11 +362,11 @@ args = [self.expr(v) for v in op.args if self.lltypemap(v) != Void] if self.lltypemap(op.result) == Void: # skip assignment of 'void' return value - return '%s(%s); if (ExceptionOccurred()) FAIL(%s)' % ( + return '%s(%s); if (RPyExceptionOccurred()) FAIL(%s)' % ( args[0], ', '.join(args[1:]), err) else: r = self.expr(op.result) - return '%s = %s(%s); if (ExceptionOccurred()) FAIL(%s)' % ( + return '%s = %s(%s); if (RPyExceptionOccurred()) FAIL(%s)' % ( r, args[0], ', '.join(args[1:]), err) # low-level operations Modified: pypy/dist/pypy/translator/c/src/exception.h ============================================================================== --- pypy/dist/pypy/translator/c/src/exception.h (original) +++ pypy/dist/pypy/translator/c/src/exception.h Mon Aug 8 16:47:56 2005 @@ -13,42 +13,42 @@ static RPYTHON_EXCEPTION_VTABLE rpython_exc_type = NULL; static RPYTHON_EXCEPTION rpython_exc_value = NULL; -#define ExceptionOccurred() (rpython_exc_type != NULL) +#define RPyExceptionOccurred() (rpython_exc_type != NULL) #define RPyRaiseException(etype, evalue) \ - assert(!ExceptionOccurred()); \ + assert(!RPyExceptionOccurred()); \ rpython_exc_type = etype; \ rpython_exc_value = evalue -#define FetchException(etypevar, evaluevar, type_of_evaluevar) \ +#define RPyFetchException(etypevar, evaluevar, type_of_evaluevar) \ etypevar = rpython_exc_type; \ evaluevar = (type_of_evaluevar) rpython_exc_value; \ rpython_exc_type = NULL; \ rpython_exc_value = NULL -#define MatchException(etype) RPYTHON_EXCEPTION_MATCH(rpython_exc_type, \ +#define RPyMatchException(etype) RPYTHON_EXCEPTION_MATCH(rpython_exc_type, \ (RPYTHON_EXCEPTION_VTABLE) etype) #ifndef PYPY_STANDALONE -static void ConvertExceptionFromCPython(void) +static void RPyConvertExceptionFromCPython(void) { /* convert the CPython exception to an RPython one */ PyObject *exc_type, *exc_value, *exc_tb; assert(PyErr_Occurred()); - assert(!ExceptionOccurred()); + assert(!RPyExceptionOccurred()); PyErr_Fetch(&exc_type, &exc_value, &exc_tb); /* XXX loosing the error message here */ rpython_exc_value = RPYTHON_PYEXCCLASS2EXC(exc_type); rpython_exc_type = RPYTHON_TYPE_OF_EXC_INST(rpython_exc_value); } -static void _ConvertExceptionToCPython(void) +static void _RPyConvertExceptionToCPython(void) { /* XXX 1. uses officially bad fishing */ /* XXX 2. looks for exception classes by name, fragile */ char* clsname; PyObject* pycls; - assert(ExceptionOccurred()); + assert(RPyExceptionOccurred()); assert(!PyErr_Occurred()); clsname = rpython_exc_type->ov_name->items; pycls = PyDict_GetItemString(PyEval_GetBuiltins(), clsname); @@ -61,8 +61,8 @@ } } -#define ConvertExceptionToCPython(vanishing) \ - _ConvertExceptionToCPython(); \ +#define RPyConvertExceptionToCPython(vanishing) \ + _RPyConvertExceptionToCPython(); \ vanishing = rpython_exc_value; \ rpython_exc_type = NULL; \ rpython_exc_value = NULL; @@ -70,20 +70,20 @@ #endif /* !PYPY_STANDALONE */ -#define RaiseSimpleException(exc, msg) \ +#define RPyRaiseSimpleException(exc, msg) \ /* XXX 1. uses officially bad fishing */ \ /* XXX 2. msg is ignored */ \ - rpython_exc_type = (exc)->o_typeptr; \ - rpython_exc_value = (exc); \ + rpython_exc_type = (R##exc)->o_typeptr; \ + rpython_exc_value = (R##exc); \ rpython_exc_value->refcount++ /******************************************************************/ #else /* non-RPython version of exceptions, using CPython only */ /******************************************************************/ -#define ExceptionOccurred() PyErr_Occurred() +#define RPyExceptionOccurred() PyErr_Occurred() #define RPyRaiseException(etype, evalue) PyErr_Restore(etype, evalue, NULL) -#define FetchException(etypevar, evaluevar, ignored) { \ +#define RPyFetchException(etypevar, evaluevar, ignored) { \ PyObject *__tb; \ PyErr_Fetch(&etypevar, &evaluevar, &__tb); \ if (evaluevar == NULL) { \ @@ -92,12 +92,12 @@ } \ Py_XDECREF(__tb); \ } -#define MatchException(etype) PyErr_ExceptionMatches(etype) -#define ConvertExceptionFromCPython() /* nothing */ -#define ConvertExceptionToCPython(vanishing) vanishing = NULL +#define RPyMatchException(etype) PyErr_ExceptionMatches(etype) +#define RPyConvertExceptionFromCPython() /* nothing */ +#define RPyConvertExceptionToCPython(vanishing) vanishing = NULL -#define RaiseSimpleException(exc, msg) \ - PyErr_SetString(Py##exc, msg) /* pun */ +#define RPyRaiseSimpleException(exc, msg) \ + PyErr_SetString(exc, msg) /* pun */ /******************************************************************/ #endif /* HAVE_RTYPER */ Modified: pypy/dist/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_os.h (original) +++ pypy/dist/pypy/translator/c/src/ll_os.h Mon Aug 8 16:47:56 2005 @@ -42,7 +42,7 @@ char buf[PATH_MAX]; int fd, namelen = RPyString_Size(filename); if (namelen >= PATH_MAX) { - RAISE_OSERROR(ENAMETOOLONG); + RPYTHON_RAISE_OSERROR(ENAMETOOLONG); return -1; } else { @@ -50,7 +50,7 @@ buf[namelen] = 0; fd = open(buf, flag, mode); if (fd < 0) - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return fd; } } @@ -59,7 +59,7 @@ { long n = read(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return n; } @@ -67,21 +67,21 @@ { long n = write(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return n; } void LL_os_close(int fd) { if (close(fd) < 0) - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); } int LL_os_dup(int fd) { fd = dup(fd); if (fd < 0) - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return fd; } @@ -91,7 +91,7 @@ char *res; res = getcwd(buf, sizeof buf); if (res == NULL) { - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return NULL; } return RPyString_FromString(buf); @@ -120,7 +120,7 @@ STRUCT_STAT st; int error = STAT(RPyString_AsString(fname), &st); if (error != 0) { - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return NULL; } return _stat_construct_result_helper(st); @@ -130,7 +130,7 @@ STRUCT_STAT st; int error = FSTAT(fd, &st); if (error != 0) { - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return NULL; } return _stat_construct_result_helper(st); @@ -156,7 +156,7 @@ res = lseek(fd, pos, how); #endif if (res < 0) - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); return res; } @@ -169,7 +169,7 @@ int res; res = ftruncate((int)fd, (off_t)length); if (res < 0) { - RAISE_OSERROR(errno); + RPYTHON_RAISE_OSERROR(errno); } } #endif Modified: pypy/dist/pypy/translator/c/src/ll_time.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_time.h (original) +++ pypy/dist/pypy/translator/c/src/ll_time.h Mon Aug 8 16:47:56 2005 @@ -60,7 +60,7 @@ unsigned long ul_millis; if (millisecs > (double)ULONG_MAX) { - RaiseSimpleException(Exc_OverflowError, + RPyRaiseSimpleException(PyExc_OverflowError, "sleep length is too large"); return; } @@ -77,7 +77,7 @@ * handler called. * Sleep(1); - RaiseSimpleException(Exc_IOError, "interrupted"); + RPyRaiseSimpleException(PyExc_IOError, "interrupted"); return; } }*/ @@ -94,7 +94,7 @@ #else if (1) { #endif - RaiseSimpleException(Exc_IOError, "select() failed"); + RPyRaiseSimpleException(PyExc_IOError, "select() failed"); return; } } Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Mon Aug 8 16:47:56 2005 @@ -10,7 +10,7 @@ #define OP_ZERO_MALLOC(size, r, err) { \ r = (void*) PyObject_Malloc(size); \ - if (r == NULL) FAIL_EXCEPTION(err, Exc_MemoryError, "out of memory")\ + if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory")\ memset((void*) r, 0, size); \ COUNT_MALLOC \ } Modified: pypy/dist/pypy/translator/c/src/support.h ============================================================================== --- pypy/dist/pypy/translator/c/src/support.h (original) +++ pypy/dist/pypy/translator/c/src/support.h Mon Aug 8 16:47:56 2005 @@ -11,13 +11,13 @@ #define FAIL_EXCEPTION(err, exc, msg) \ { \ - RaiseSimpleException(exc, msg); \ + RPyRaiseSimpleException(exc, msg); \ FAIL(err) \ } -#define FAIL_OVF(err, msg) FAIL_EXCEPTION(err, Exc_OverflowError, msg) -#define FAIL_VAL(err, msg) FAIL_EXCEPTION(err, Exc_ValueError, msg) -#define FAIL_ZER(err, msg) FAIL_EXCEPTION(err, Exc_ZeroDivisionError, msg) -#define CFAIL(err) { ConvertExceptionFromCPython(); FAIL(err) } +#define FAIL_OVF(err, msg) FAIL_EXCEPTION(err, PyExc_OverflowError, msg) +#define FAIL_VAL(err, msg) FAIL_EXCEPTION(err, PyExc_ValueError, msg) +#define FAIL_ZER(err, msg) FAIL_EXCEPTION(err, PyExc_ZeroDivisionError, msg) +#define CFAIL(err) { RPyConvertExceptionFromCPython(); FAIL(err) } #ifndef PYPY_STANDALONE From cfbolz at codespeak.net Mon Aug 8 16:48:07 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 16:48:07 +0200 (CEST) Subject: [pypy-svn] r15772 - pypy/dist/pypy/rpython/memory Message-ID: <20050808144807.6DA1727B4E@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 16:48:06 2005 New Revision: 15772 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py Log: check whether a link has an llexitcase before touching it. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Mon Aug 8 16:48:06 2005 @@ -118,7 +118,8 @@ def visit(obj): if isinstance(obj, Link): collect_args(obj.args) - constants[Constant(obj.llexitcase)] = None + if hasattr(obj, "llexitcase"): + constants[Constant(obj.llexitcase)] = None elif isinstance(obj, Block): for op in obj.operations: collect_args(op.args) @@ -189,7 +190,8 @@ def visit(obj): if isinstance(obj, Link): patch_consts(obj.args) - if Constant(obj.llexitcase) in self.constants: + if (hasattr(obj, "llexitcase") and + Constant(obj.llexitcase) in self.constants): obj.llexitcase = self.constants[Constant(obj.llexitcase)] elif isinstance(obj, Block): for op in obj.operations: From adim at codespeak.net Mon Aug 8 16:51:47 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Mon, 8 Aug 2005 16:51:47 +0200 (CEST) Subject: [pypy-svn] r15773 - in pypy/dist/pypy/interpreter: astcompiler stablecompiler Message-ID: <20050808145147.B3A8C27B49@code1.codespeak.net> Author: adim Date: Mon Aug 8 16:51:44 2005 New Revision: 15773 Modified: pypy/dist/pypy/interpreter/astcompiler/transformer.py pypy/dist/pypy/interpreter/stablecompiler/transformer.py Log: use empty lists instead of emtpy tuples for arglist Modified: pypy/dist/pypy/interpreter/astcompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/transformer.py Mon Aug 8 16:51:44 2005 @@ -254,7 +254,8 @@ if args[0] == symbol.varargslist: names, defaults, flags = self.com_arglist(args[1:]) else: - names = defaults = () + names = [] + defaults = [] flags = 0 doc = self.get_docstring(nodelist[-1]) Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Mon Aug 8 16:51:44 2005 @@ -253,7 +253,8 @@ if args[0] == symbol.varargslist: names, defaults, flags = self.com_arglist(args[1:]) else: - names = defaults = () + names = [] + defaults = [] flags = 0 doc = self.get_docstring(nodelist[-1]) @@ -702,7 +703,7 @@ def atom_lsqb(self, nodelist): if nodelist[1][0] == token.RSQB: - return List(()) + return List([]) return self.com_list_constructor(nodelist[1]) def atom_lbrace(self, nodelist): From adim at codespeak.net Mon Aug 8 16:54:56 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Mon, 8 Aug 2005 16:54:56 +0200 (CEST) Subject: [pypy-svn] r15774 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050808145456.DCCBA27B49@code1.codespeak.net> Author: adim Date: Mon Aug 8 16:54:54 2005 New Revision: 15774 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - added getattr implementation (for rvalue only) - added simple funcdefs implementation Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Aug 8 16:54:54 2005 @@ -2,6 +2,7 @@ from grammar import BaseGrammarBuilder, AbstractContext from pypy.interpreter.astcompiler import ast, consts +from pypy.interpreter.astcompiler.transformer import WalkerError import pypy.interpreter.pyparser.pysymbol as sym import pypy.interpreter.pyparser.pytoken as tok @@ -113,15 +114,18 @@ raise ValueError, "unexpected tokens (%d): %s" % (nb,[ str(i) for i in L] ) -def build_power( builder, nb ): - L = get_atoms( builder, nb ) +def build_power(builder, nb): + L = get_atoms(builder, nb) if len(L) == 1: builder.push( L[0] ) elif len(L) == 2: arguments, stararg, dstararg = L[1].value builder.push(ast.CallFunc(L[0], arguments, stararg, dstararg)) elif len(L) == 3: - builder.push(ast.Power([L[0], L[2]])) + if isinstance(L[1], TokenObject) and L[1].name == tok.DOT: + builder.push(ast.Getattr(L[0], L[2].value)) + else: + builder.push(ast.Power([L[0], L[2]])) else: raise ValueError, "unexpected tokens: %s" % L @@ -257,7 +261,7 @@ return build_binary_expr( builder, nb, ast.And ) def build_test( builder, nb ): - return build_binary_expr( builder, nb, ast.Or) + return build_binary_expr(builder, nb, ast.Or) def build_testlist( builder, nb ): return build_binary_expr( builder, nb, ast.Tuple ) @@ -310,6 +314,15 @@ nodes.append(node) builder.push( ast.Stmt(nodes) ) +def build_return_stmt(builder, nb): + L = get_atoms(builder, nb) + if len(L) > 2: + assert False, "return several stmts not implemented" + elif len(L) == 1: + builder.push(ast.Return(Const(None), None)) # XXX lineno + else: + builder.push(ast.Return(L[1], None)) # XXX lineno + def build_file_input(builder, nb): # FIXME: need to handle docstring ! doc = None @@ -380,6 +393,12 @@ elif len(L) == 3: # '(' Arglist ')' # push arglist on the stack builder.push(L[1]) + elif len(L) == 2: + # Attribute access: '.' NAME + # XXX Warning: fails if trailer is used in lvalue + builder.push(L[0]) + builder.push(L[1]) + builder.push(TempRuleObject('pending-attr-access', 2, None)) else: assert False, "Trailer reducing implementation incomplete !" @@ -406,6 +425,24 @@ builder.push(ast.List(nodes)) +def build_funcdef(builder, nb): + """funcdef: [decorators] 'def' NAME parameters ':' suite + """ + L = get_atoms(builder, nb) + funcname = L[1] + arglist = [] + index = 3 + while not (isinstance(L[index], TokenObject) and L[index].name == tok.RPAR): + arglist.append(L[index]) + index += 1 + names, default, flags = parse_arglist(arglist) + funcname = L[1].value + arglist = L[2] + code = L[-1] # FIXME: suite is not reduced ! + # FIXME: decorators and docstring ! + builder.push(ast.Function(None, funcname, names, default, flags, None, code)) + + def parse_argument(tokens): """parses function call arguments""" l = len(tokens) @@ -579,6 +616,9 @@ sym.trailer : build_trailer, sym.arglist : build_arglist, sym.listmaker : build_listmaker, + sym.funcdef : build_funcdef, + sym.return_stmt : build_return_stmt, + # sym.parameters : build_parameters, } class RuleObject(ast.Node): @@ -667,6 +707,8 @@ self.rule_stack.append( obj ) if not isinstance(obj, RuleObject) and not isinstance(obj, TokenObject): print "Pushed:", str(obj), len(self.rule_stack) + elif isinstance(obj, TempRuleObject): + print "Pushed:", str(obj), len(self.rule_stack) # print "\t", self.rule_stack def push_tok(self, name, value, src ): Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Mon Aug 8 16:54:54 2005 @@ -61,6 +61,7 @@ dictmakers = [ "l = {a : b, 'c' : 0}", + "l = {}", ] backtrackings = [ @@ -94,6 +95,24 @@ 'a = b = c = d', ] +attraccess = [ + # 'a.b = 2', # Module(None, Stmt([Assign([AssAttr(Name('a'), 'b', 'OP_ASSIGN')], Const(2))])) + 'x = a.b', + ] + + +one_stmt_funcdefs = [ + "def f(): return 1", + "def f(x): return x+1", + "def f(x,y): return x+y", + "def f(x,y=1,z=t): return x+y", + "def f(x,y=1,z=t,*args,**kwargs): return x+y", + "def f(x,y=1,z=t,*args): return x+y", + "def f(x,y=1,z=t,**kwargs): return x+y", + "def f(*args): return 1", + "def f(**kwargs): return 1", + ] + TESTS = [ expressions, comparisons, @@ -103,6 +122,11 @@ genexps, dictmakers, multiexpr, + attraccess, + ] + +EXEC_INPUTS = [ +one_stmt_funcdefs, ] TARGET_DICT = { @@ -137,6 +161,11 @@ for expr in family: yield check_expression, expr +def test_exec_inputs(): + for family in EXEC_INPUTS: + for expr in family: + yield check_expression, expr, 'exec' + SNIPPETS = [ 'snippet_1.py', From cfbolz at codespeak.net Mon Aug 8 17:08:45 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 17:08:45 +0200 (CEST) Subject: [pypy-svn] r15775 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050808150845.57C6227B49@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 17:08:44 2005 New Revision: 15775 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: make sure that a real bools are returned. Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Mon Aug 8 17:08:44 2005 @@ -88,6 +88,8 @@ """XXX A nice docstring here""" if isinstance(T, (lltype.Struct, lltype.Array)): return simulatorptr(lltype.Ptr(T), address) + elif T == lltype.Bool: + return bool(address._load(primitive_to_fmt[T])[0]) elif isinstance(T, lltype.Primitive): return address._load(primitive_to_fmt[T])[0] elif isinstance(T, lltype.Ptr): @@ -129,6 +131,8 @@ base = self._layout[field_name] if isinstance(T, lltype.Primitive): res = (self._address + offset)._load(primitive_to_fmt[T])[0] + if T == lltype.Bool: + res = bool(res) return res elif isinstance(T, lltype.Ptr): res = _expose(T.TO, (self._address + offset).address[0]) Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Mon Aug 8 17:08:44 2005 @@ -18,7 +18,8 @@ assert s0.a == 42 assert s0.b == 43 assert s0.c == 'x' - assert s0.d == 1 + assert s0.d == True + assert lltype.typeOf(s0.d) == lltype.Bool s0.a = 1 s0.b = s0.a assert s0.a == 1 @@ -37,6 +38,16 @@ x[2].v = 3 assert [x[z].v for z in range(3)] == [1, 2, 3] +def test_bool_array(): + Ar = lltype.GcArray(lltype.Bool) + x = malloc(Ar, 3) + assert len(x) == 3 + assert lltype.typeOf(x[0]) == lltype.Bool + x[0] = True + x[1] = False + x[2] = False + assert [x[z] for z in range(3)] == [True, False, False] + def define_list(T): List_typ = lltype.GcStruct( From cfbolz at codespeak.net Mon Aug 8 17:09:27 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 17:09:27 +0200 (CEST) Subject: [pypy-svn] r15777 - pypy/dist/pypy/rpython/memory Message-ID: <20050808150927.4895327B4E@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 17:09:26 2005 New Revision: 15777 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py Log: don't try to convert constant functions in the graph. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Mon Aug 8 17:09:26 2005 @@ -8,7 +8,7 @@ from pypy.objspace.flow.model import Constant from pypy.rpython import lltype -import struct +import types, struct class LLTypeConverter(object): def __init__(self, address): @@ -139,6 +139,8 @@ continue elif isinstance(cand, lltype.LowLevelType): continue + elif isinstance(cand, types.FunctionType): + continue elif isinstance(cand, str): continue elif isinstance(lltype.typeOf(cand), lltype.Primitive): @@ -179,6 +181,8 @@ self.constants[constant] = constant.value elif isinstance(constant.value, str): self.constants[constant] = constant.value + elif isinstance(constant.value, types.FunctionType): + self.constants[constant] = constant.value else: self.constants[constant] = self.cvter.convert(constant.value) From nik at codespeak.net Mon Aug 8 17:23:38 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Mon, 8 Aug 2005 17:23:38 +0200 (CEST) Subject: [pypy-svn] r15778 - pypy/dist/pypy/module/_sre Message-ID: <20050808152338.7663A27B40@code1.codespeak.net> Author: nik Date: Mon Aug 8 17:23:37 2005 New Revision: 15778 Modified: pypy/dist/pypy/module/_sre/app_sre.py Log: more optimizations Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Mon Aug 8 17:23:37 2005 @@ -352,14 +352,36 @@ return has_matched def search(self, pattern_codes): + flags = 0 if pattern_codes[0] == OPCODES["info"]: # optimization info block # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: return self.fast_search(pattern_codes) + flags = pattern_codes[2] pattern_codes = pattern_codes[pattern_codes[1] + 1:] - # XXX literal and charset optimizations missing here + string_position = self.start + if pattern_codes[0] == OPCODES["literal"]: + # Special case: Pattern starts with a literal character. This is + # used for short prefixes + character = pattern_codes[1] + while True: + while string_position < self.end \ + and ord(self.string[string_position]) != character: + string_position += 1 + if string_position >= self.end: + return False + self.start = string_position + string_position += 1 + self.string_position = string_position + if flags & SRE_INFO_LITERAL: + return True + if self.match(pattern_codes[2:]): + return True + return False + + # General case while string_position <= self.end: self.reset() self.start = self.string_position = string_position @@ -744,20 +766,40 @@ ctx.has_matched = True yield True - # XXX OP_LITERAL optimization missing here - - # backtracking ctx.state.marks_push() - while count >= mincount: - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(ctx.peek_code(1) + 1) - yield False - if child_context.has_matched: - ctx.has_matched = True - yield True - ctx.skip_char(-1) - count -= 1 - ctx.state.marks_pop_keep() + if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["literal"]: + # Special case: Tail starts with a literal. Skip positions where + # the rest of the pattern cannot possibly match. + char = ctx.peek_code(ctx.peek_code(1) + 2) + while True: + while count >= mincount and \ + (ctx.at_end() or ord(ctx.peek_char()) != char): + ctx.skip_char(-1) + count -= 1 + if count < mincount: + break + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.skip_char(-1) + count -= 1 + ctx.state.marks_pop_keep() + + else: + # General case: backtracking + while count >= mincount: + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.skip_char(-1) + count -= 1 + ctx.state.marks_pop_keep() ctx.state.marks_pop_discard() ctx.has_matched = False From cfbolz at codespeak.net Mon Aug 8 18:27:49 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 8 Aug 2005 18:27:49 +0200 (CEST) Subject: [pypy-svn] r15781 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050808162749.1927927B41@code1.codespeak.net> Author: cfbolz Date: Mon Aug 8 18:27:48 2005 New Revision: 15781 Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: failing test for conversion of casted substructure Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Mon Aug 8 18:27:48 2005 @@ -118,3 +118,12 @@ fpter = cvter.convert(llfuncptr) assert fpter(1, 2) == 3 +def DONOTtest_convertsubstructure(): + cvter = LLTypeConverter(lladdress.raw_malloc(100)) + S1 = lltype.GcStruct("s1", ("v1", lltype.Signed)) + S2 = lltype.GcStruct("s2", ("s", S1), ("v2", lltype.Signed)) + lls2 = lltype.malloc(S2) + lls1 = lltype.cast_pointer(lltype.Ptr(S1), lls2) + s1 = cvter.convert(lls1) + s2 = cast_pointer(lltype.Ptr(S2), s1) + assert s2.v2 == 0 From pedronis at codespeak.net Mon Aug 8 18:35:47 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 8 Aug 2005 18:35:47 +0200 (CEST) Subject: [pypy-svn] r15782 - in pypy/dist/pypy/translator: . c c/test Message-ID: <20050808163547.54B5427B41@code1.codespeak.net> Author: pedronis Date: Mon Aug 8 18:35:43 2005 New Revision: 15782 Modified: pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/support.py pypy/dist/pypy/translator/c/test/test_database.py pypy/dist/pypy/translator/gensupp.py Log: issue107 in-progress in genc attach a global prefix to uniquename generated names (pypy_), some effort to avoid to have more than one 'pypy_' substring in a name. open questions: Do we think the prefixes OP_ LL_ and especially FAIL are safe enough? what to do about local var names? Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Mon Aug 8 18:35:43 2005 @@ -34,10 +34,12 @@ basename = STRUCT._name with_number = True else: - basename = db.gettypedefnode(STRUCT).name + basename = db.gettypedefnode(STRUCT).barename basename = '%s_len%d' % (basename, varlength) with_number = False - self.name = db.namespace.uniquename(basename, with_number=with_number) + (self.barename, + self.name) = db.namespace.uniquename(basename, with_number=with_number, + bare=True) self.dependencies = {} self.prefix = somelettersfrom(STRUCT._name) + '_' @@ -73,7 +75,7 @@ # do we need deallocator(s)? if self.refcount and varlength == 1: - self.deallocator = db.namespace.uniquename('dealloc_'+self.name) + self.deallocator = db.namespace.uniquename('dealloc_'+self.barename) # are two deallocators needed (a dynamic one for DECREF, which checks # the real type of the structure and calls the static deallocator) ? @@ -85,7 +87,7 @@ pass if rtti is not None: self.static_deallocator = db.namespace.uniquename( - 'staticdealloc_'+self.name) + 'staticdealloc_'+self.barename) fnptr = rtti._obj.query_funcptr if fnptr is None: raise NotImplementedError( @@ -183,10 +185,12 @@ basename = 'array' with_number = True else: - basename = db.gettypedefnode(ARRAY).name + basename = db.gettypedefnode(ARRAY).barename basename = '%s_len%d' % (basename, varlength) with_number = False - self.name = db.namespace.uniquename(basename, with_number=with_number) + (self.barename, + self.name) = db.namespace.uniquename(basename, with_number=with_number, + bare=True) self.dependencies = {} # look up the reference counter field @@ -201,7 +205,7 @@ # is a specific deallocator needed? if self.refcount and varlength == 1 and list(self.deallocator_lines('')): - self.deallocator = db.namespace.uniquename('dealloc_'+self.name) + self.deallocator = db.namespace.uniquename('dealloc_'+self.barename) def access_expr(self, baseexpr, index): return '%s.items[%d]' % (baseexpr, index) Modified: pypy/dist/pypy/translator/c/support.py ============================================================================== --- pypy/dist/pypy/translator/c/support.py (original) +++ pypy/dist/pypy/translator/c/support.py Mon Aug 8 18:35:43 2005 @@ -44,8 +44,8 @@ class CNameManager(NameManager): - def __init__(self): - NameManager.__init__(self) + def __init__(self, global_prefix='pypy_'): + NameManager.__init__(self, global_prefix=global_prefix) # keywords cannot be reused. This is the C99 draft's list. self.make_reserved_names(''' auto enum restrict unsigned Modified: pypy/dist/pypy/translator/c/test/test_database.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_database.py (original) +++ pypy/dist/pypy/translator/c/test/test_database.py Mon Aug 8 18:35:43 2005 @@ -33,19 +33,21 @@ def test_struct(): db = LowLevelDatabase() + pfx = db.namespace.global_prefix + 'g_' S = GcStruct('test', ('x', Signed)) s = malloc(S) s.x = 42 - assert db.get(s).startswith('(&g_') + assert db.get(s).startswith('(&'+pfx) assert db.containernodes.keys() == [s._obj] assert db.structdefnodes.keys() == [S] def test_inlined_struct(): db = LowLevelDatabase() + pfx = db.namespace.global_prefix + 'g_' S = GcStruct('test', ('x', Struct('subtest', ('y', Signed)))) s = malloc(S) s.x.y = 42 - assert db.get(s).startswith('(&g_') + assert db.get(s).startswith('(&'+pfx) assert db.containernodes.keys() == [s._obj] assert len(db.structdefnodes) == 2 assert S in db.structdefnodes @@ -53,12 +55,13 @@ def test_complete(): db = LowLevelDatabase() + pfx = db.namespace.global_prefix + 'g_' T = GcStruct('subtest', ('y', Signed)) S = GcStruct('test', ('x', Ptr(T))) s = malloc(S) s.x = malloc(T) s.x.y = 42 - assert db.get(s).startswith('(&g_') + assert db.get(s).startswith('(&'+pfx) assert db.containernodes.keys() == [s._obj] db.complete() assert len(db.containernodes) == 2 Modified: pypy/dist/pypy/translator/gensupp.py ============================================================================== --- pypy/dist/pypy/translator/gensupp.py (original) +++ pypy/dist/pypy/translator/gensupp.py Mon Aug 8 18:35:43 2005 @@ -85,10 +85,11 @@ # while always keeping all globals visible. class NameManager(object): - def __init__(self): + def __init__(self, global_prefix=''): self.seennames = {} self.scope = 0 self.scopelist = [] + self.global_prefix = global_prefix def make_reserved_names(self, txt): """add names to list of known names. If one exists already, @@ -99,7 +100,7 @@ raise NameError, "%s has already been seen!" self.seennames[name] = 1 - def uniquename(self, basename, with_number=None): + def uniquename(self, basename, with_number=None, bare=False): basename = basename.translate(C_IDENTIFIER) n = self.seennames.get(basename, 0) self.seennames[basename] = n+1 @@ -107,13 +108,20 @@ with_number = basename in ('v', 'w_') if with_number: if n == 0: - return '%s%d' % (basename, n) + newname = '%s%d' % (basename, n) + if bare: + return newname, self.global_prefix + newname + else: + return self.global_prefix + newname else: - return self.uniquename('%s%d' % (basename, n)) + return self.uniquename('%s%d' % (basename, n), bare=bare) if n == 0: - return basename + if bare: + return basename, self.global_prefix + basename + else: + return self.global_prefix + basename else: - return self.uniquename('%s_%d' % (basename, n)) + return self.uniquename('%s_%d' % (basename, n), bare=bare) def localScope(self, parent=None): ret = _LocalScope(self, parent) From adim at codespeak.net Mon Aug 8 18:42:00 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Mon, 8 Aug 2005 18:42:00 +0200 (CEST) Subject: [pypy-svn] r15783 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050808164200.7B65327B49@code1.codespeak.net> Author: adim Date: Mon Aug 8 18:41:57 2005 New Revision: 15783 Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_function.py Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - reduce suite (might be some problems on single_inputs) - implemented if_stmts - added a simple function (with several statements) test case Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Aug 8 18:41:57 2005 @@ -292,7 +292,7 @@ assert l==3 lvalue = L[0] assert is_augassign( lvalue ) - builder.push( ast.AugAssign( lvalue, op, L[2] ) ) + builder.push( ast.AugAssign( lvalue, op.get_name(), L[2] ) ) def return_one( builder, nb ): L = get_atoms( builder, nb ) @@ -312,7 +312,7 @@ nodes.append(ast.Discard(ast.Const(None))) else: nodes.append(node) - builder.push( ast.Stmt(nodes) ) + builder.push(ast.Stmt(nodes)) def build_return_stmt(builder, nb): L = get_atoms(builder, nb) @@ -338,7 +338,9 @@ stmts.extend(node.nodes) elif isinstance(node, TokenObject) and node.name == tok.ENDMARKER: # XXX Can't we just remove the last element of the list ? - break + break + elif isinstance(node, TokenObject) and node.name == tok.NEWLINE: + continue else: stmts.append(node) return builder.push(ast.Module(doc, ast.Stmt(stmts))) @@ -348,9 +350,8 @@ l = len(L) if l >= 1: builder.push(ast.Module(None, L[0])) - return - raise WalkerError("error") - + else: + assert False, "Forbidden path" def build_testlist_gexp(builder, nb): L = get_atoms(builder, nb) @@ -438,11 +439,50 @@ names, default, flags = parse_arglist(arglist) funcname = L[1].value arglist = L[2] - code = L[-1] # FIXME: suite is not reduced ! + code = L[-1] # FIXME: decorators and docstring ! builder.push(ast.Function(None, funcname, names, default, flags, None, code)) +def build_suite(builder, nb): + """suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT""" + L = get_atoms(builder, nb) + if len(L) == 1: + builder.push(L[0]) + elif len(L) == 4: + # Only one statement for (stmt+) + stmt = L[2] + builder.push(L[2]) + else: + # several statements + stmts = [] + nodes = L[2:-1] + for node in nodes: + if isinstance(node, ast.Stmt): + stmts.extend(node.nodes) + else: + stmts.append(node) + builder.push(ast.Stmt(stmts)) + + +def build_if_stmt(builder, nb): + L = get_atoms(builder, nb) + tests = [] + tests.append((L[1], L[3])) + index = 4 + else_ = None + while index < len(L): + cur_token = L[index] + assert isinstance(cur_token, TokenObject) # rtyper + if cur_token.value == 'elif': + tests.append((L[index+1], L[index+3])) + index += 4 + else: # cur_token.value == 'else' + else_ = L[index+2] + break # break is not necessary + builder.push(ast.If(tests, else_)) + + def parse_argument(tokens): """parses function call arguments""" l = len(tokens) @@ -618,6 +658,8 @@ sym.listmaker : build_listmaker, sym.funcdef : build_funcdef, sym.return_stmt : build_return_stmt, + sym.suite : build_suite, + sym.if_stmt : build_if_stmt, # sym.parameters : build_parameters, } @@ -654,15 +696,15 @@ self.line = 0 # src.getline() self.col = 0 # src.getcol() + def get_name(self): + return tok.tok_rpunct.get(self.name, tok.tok_name.get(self.name,str(self.name))) + def __str__(self): - return "" % (tok.tok_rpunct.get(self.name, - tok.tok_name.get(self.name,str(self.name))), - self.value) + return "" % (self.get_name(), self.value) def __repr__(self): - return "" % (tok.tok_rpunct.get(self.name, - tok.tok_name.get(self.name,str(self.name))), - self.value) + return "" % (self.get_name(), self.value) + class ArglistObject(ast.Node): """helper class to build function's arg list""" Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_function.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_function.py Mon Aug 8 18:41:57 2005 @@ -0,0 +1,6 @@ +def f(a, b=1, *args, **kwargs): + if args: + a += len(args) + if kwargs: + a += len(kwargs) + return a*b Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Mon Aug 8 18:41:57 2005 @@ -100,6 +100,16 @@ 'x = a.b', ] +if_stmts = [ + "if a == 1: a+= 2", + """if a == 1: + a += 2 +elif a == 2: + a += 3 +else: + a += 4 +""" + ] one_stmt_funcdefs = [ "def f(): return 1", @@ -126,7 +136,8 @@ ] EXEC_INPUTS = [ -one_stmt_funcdefs, + one_stmt_funcdefs, + if_stmts, ] TARGET_DICT = { @@ -170,6 +181,7 @@ SNIPPETS = [ 'snippet_1.py', 'snippet_several_statements.py', + 'snippet_simple_function.py', # 'snippet_2.py', # 'snippet_3.py', # 'snippet_4.py', From ale at codespeak.net Mon Aug 8 20:06:30 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 8 Aug 2005 20:06:30 +0200 (CEST) Subject: [pypy-svn] r15784 - in pypy/dist/pypy/lib: . test2 Message-ID: <20050808180630.0DD0A27B40@code1.codespeak.net> Author: ale Date: Mon Aug 8 20:06:29 2005 New Revision: 15784 Added: pypy/dist/pypy/lib/test2/test_deque_extra.py Modified: pypy/dist/pypy/lib/collections.py Log: changed deque from a generator to an iterator, since test_iterlen expects to get the length of the running iterator. Some test added Modified: pypy/dist/pypy/lib/collections.py ============================================================================== --- pypy/dist/pypy/lib/collections.py (original) +++ pypy/dist/pypy/lib/collections.py Mon Aug 8 20:06:29 2005 @@ -134,29 +134,12 @@ del self.__dict__[threadlocalattr] def __iter__(self): - block = self.left - while block: - l, r = 0, n - if block is self.left: - l = self.leftndx - if block is self.right: - r = self.rightndx + 1 - for elem in block[l:r]: - yield elem - block = block[RGTLNK] + return dequeIterator(self) + def __reversed__(self): - block = self.right - while block: - l, r = 0, n - if block is self.left: - l = self.leftndx - if block is self.right: - r = self.rightndx + 1 - for elem in reversed(block[l:r]): - yield elem - block = block[LFTLNK] - + return dequeIterator(self,True) + def __len__(self): sum = 0 block = self.left @@ -264,3 +247,38 @@ else: return NotImplemented +class dequeIterator: + + def __init__(self, dequeobj, reverse=False): + self.deque = dequeobj + self.length = len(dequeobj) + self.consumed = 0 + if reverse: + self.index = self.length-1 + self.inc = -1 + else: + self.index = 0 + self.inc = 1 + self.reverse = reverse + + def __iter__(self): + return self + + def next(self): + if self.length == len(self.deque): + if self.index < self.length and self.index >= 0: + res = self.deque[self.index] + self.index += self.inc + self.consumed += 1 + return res + else: + raise StopIteration + else: + self.deque = [] + self.index = 0 + self.length = self.consumed = 0 + raise RuntimeError("deque mutated during iteration") + + def __len__(self): + return self.length - self.consumed + \ No newline at end of file Added: pypy/dist/pypy/lib/test2/test_deque_extra.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/test2/test_deque_extra.py Mon Aug 8 20:06:29 2005 @@ -0,0 +1,38 @@ +# Deque Tests + + + +n = 10 +class Test_deque: + def setup_method(self,method): + + from pypy.lib.collections import deque + self.d = deque(range(n)) + + def test_deque(self): + + assert len(self.d) == n + for i in range(n): + assert i == self.d[i] + for i in reversed(range(n)): + assert self.d.pop() == i + + def test_deque_iter(self): + it = iter(self.d) + assert len(it) == n + assert it.next() == 0 + assert len(it) == n-1 + self.d.pop() + raises(RuntimeError,it.next) + assert len(it) == 0 + assert list(it) == [] + + def test_deque_reversed(self): + it = reversed(self.d) + assert len(it) == n + assert it.next() == n-1 + assert len(it) == n-1 + self.d.pop() + raises(RuntimeError,it.next) + assert len(it) == 0 + assert list(it) == [] \ No newline at end of file From ale at codespeak.net Mon Aug 8 20:12:16 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 8 Aug 2005 20:12:16 +0200 (CEST) Subject: [pypy-svn] r15785 - pypy/dist/pypy/module/__builtin__ Message-ID: <20050808181216.5496C27B40@code1.codespeak.net> Author: ale Date: Mon Aug 8 20:12:14 2005 New Revision: 15785 Modified: pypy/dist/pypy/module/__builtin__/__init__.py pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/module/__builtin__/operation.py Log: changed xrange and reversed from a generator to an iterator, since test_iterlen expects to get the length of the running iterator. reversed is moved from app level to interplevel and from app_functional to operation Modified: pypy/dist/pypy/module/__builtin__/__init__.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/__init__.py (original) +++ pypy/dist/pypy/module/__builtin__/__init__.py Mon Aug 8 20:12:14 2005 @@ -28,7 +28,7 @@ 'enumerate' : 'app_functional.enumerate', 'xrange' : 'app_functional.xrange', 'sorted' : 'app_functional.sorted', - 'reversed' : 'app_functional.reversed', + #'reversed' : 'app_functional.reversed', 'issubclass' : 'app_inspect.issubclass', 'isinstance' : 'app_inspect.isinstance', @@ -79,6 +79,7 @@ '_isfake' : 'special._isfake', # interp-level function definitions + 'reversed' : 'operation.interp_reversed', 'abs' : 'operation.abs', 'chr' : 'operation.chr', 'unichr' : 'operation.unichr', Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Mon Aug 8 20:12:14 2005 @@ -282,7 +282,8 @@ n = get_len_of_range(stop, start, -step) self.start = start self.len = n - self.step = step + self.step = step + self.index = 0 def __str__(self): stop = self.start + self.len * self.step @@ -296,7 +297,7 @@ __repr__ = __str__ def __len__(self): - return self.len + return self.len - self.index def __getitem__(self, index): # xrange does NOT support slicing @@ -310,10 +311,16 @@ raise IndexError, "xrange object index out of range" def __iter__(self): - i = 0 - while i < self.len: - yield self.start + i * self.step - i += 1 + return self + + def next(self): + #i = 0 + if self.index < self.len: + res = self.start + self.index * self.step + self.index += 1 + return res + else: + raise StopIteration # ____________________________________________________________ @@ -323,16 +330,3 @@ sorted_lst.sort(cmp, key, reverse) return sorted_lst -def reversed(iterable): - """reversed(sequence) -> reverse iterator over values of the sequence - - Return a reverse iterator - """ - if hasattr(iterable, '__reversed__'): - return iterable.__reversed__() - seq = list(iterable) - def reversed_gen(local_iterable): - len_iterable = len(local_iterable) - for index in range(len_iterable-1, -1, -1): - yield local_iterable[index] - return reversed_gen(seq) Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Mon Aug 8 20:12:14 2005 @@ -7,6 +7,20 @@ from pypy.interpreter.error import OperationError NoneNotWrapped = gateway.NoneNotWrapped + +from pypy.objspace.std.iterobject import W_SeqIterObject + +def interp_reversed(space,w_iterable): + # if obj has __reversed__ call and return it + + func = space.lookup(w_iterable,'__reversed__') + if func : + return space.call_function(func,w_iterable) + # else return W_IterObject with reverse set + else: + w_seq = W_SeqIterObject(space,w_iterable,-1,True) + return w_seq + def abs(space, w_val): "abs(number) -> number\n\nReturn the absolute value of the argument." return space.abs(w_val) From ale at codespeak.net Mon Aug 8 20:13:50 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 8 Aug 2005 20:13:50 +0200 (CEST) Subject: [pypy-svn] r15786 - pypy/dist/pypy/objspace/std Message-ID: <20050808181350.A4CD027B40@code1.codespeak.net> Author: ale Date: Mon Aug 8 20:13:49 2005 New Revision: 15786 Modified: pypy/dist/pypy/objspace/std/dictobject.py Log: added a check for w_dict.len == -1 signaling an invalid iterator Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Mon Aug 8 20:13:49 2005 @@ -362,7 +362,7 @@ def len__DictIterObject(space, w_dictiter): w_dict = w_dictiter.w_dictobject - if w_dict is None: + if w_dict is None or w_dictiter.len == -1 : return space.wrap(0) return space.wrap(w_dictiter.len - w_dictiter.pos) # ____________________________________________________________ From ale at codespeak.net Mon Aug 8 20:17:20 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 8 Aug 2005 20:17:20 +0200 (CEST) Subject: [pypy-svn] r15787 - pypy/dist/pypy/objspace/std Message-ID: <20050808181720.18E5727B41@code1.codespeak.net> Author: ale Date: Mon Aug 8 20:17:19 2005 New Revision: 15787 Modified: pypy/dist/pypy/objspace/std/iterobject.py Log: added support for reverse iteration in W_SeqIterObject Modified: pypy/dist/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/iterobject.py (original) +++ pypy/dist/pypy/objspace/std/iterobject.py Mon Aug 8 20:17:19 2005 @@ -10,10 +10,21 @@ class W_SeqIterObject(W_Object): from pypy.objspace.std.itertype import iter_typedef as typedef - def __init__(w_self, space, w_seq, index=0): + def __init__(w_self, space, w_seq, index=0, reverse=False): W_Object.__init__(w_self, space) w_self.w_seq = w_seq + try: + w_self.length = space.unwrap(space.len(w_seq)) + except OperationError,e: + if e.match(space, space.w_TypeError): + w_self.length = 0 + else: + raise w_self.index = index + if index < 0: + w_self.index += w_self.length + w_self.reverse = reverse + w_self.consumed = 0 registerimplementation(W_SeqIterObject) @@ -23,21 +34,36 @@ def next__SeqIter(space, w_seqiter): if w_seqiter.w_seq is None: - raise OperationError(space.w_StopIteration, space.w_None) + raise OperationError(space.w_StopIteration, space.w_None) try: - w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index)) + if w_seqiter.index >=0: + w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index)) + else: + raise OperationError(space.w_StopIteration, space.w_None) except OperationError, e: w_seqiter.w_seq = None if not e.match(space, space.w_IndexError): raise raise OperationError(space.w_StopIteration, space.w_None) - w_seqiter.index += 1 + if w_seqiter.reverse: + w_seqiter.index -= 1 + else: + w_seqiter.index += 1 + w_seqiter.consumed += 1 return w_item def len__SeqIter(space, w_seqiter): - if w_seqiter.w_seq is None: + if w_seqiter.w_seq is None : return space.wrap(0) - w_len = space.sub(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.index)) + w_index = space.sub(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.index)) + if space.is_true(space.gt(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.index))): + if w_seqiter.reverse: + w_len = space.wrap(w_seqiter.index+1) + else: + w_len = space.sub(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.consumed)) + else: + w_seqiter.w_seq = None + w_len = space.wrap(0) return w_len register_all(vars()) From ale at codespeak.net Mon Aug 8 20:19:04 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 8 Aug 2005 20:19:04 +0200 (CEST) Subject: [pypy-svn] r15788 - pypy/dist/pypy/objspace/std Message-ID: <20050808181904.1238027B41@code1.codespeak.net> Author: ale Date: Mon Aug 8 20:19:03 2005 New Revision: 15788 Modified: pypy/dist/pypy/objspace/std/listtype.py Log: rewrote __reversed__ for list in interpreter level using W_SeqIterObject support for reverse iteration Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Mon Aug 8 20:19:03 2005 @@ -1,5 +1,6 @@ from __future__ import generators from pypy.objspace.std.stdtypedef import * +from pypy.objspace.std.iterobject import W_SeqIterObject from pypy.objspace.std.register_all import register_all from sys import maxint @@ -13,17 +14,21 @@ list_reverse = MultiMethod('reverse',1) list_sort = MultiMethod('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse']) list_reversed = MultiMethod('__reversed__', 1) - -# gateway is imported in the stdtypedef module -list_reversed__ANY = gateway.applevel(''' - # NOT_RPYTHON -- uses yield - - def reversed(lst): - for index in range(len(lst)-1, -1, -1): - yield lst[index] - -''', filename=__file__).interphook('reversed') - +## +### gateway is imported in the stdtypedef module +##list_reversed__ANY = gateway.applevel(''' +## # NOT_RPYTHON -- uses yield +## +## def reversed(lst): +## return iter([x for x in lst[::-1]]) +## # for index in range(len(lst)-1, -1, -1): +## # yield lst[index] +## +##''', filename=__file__).interphook('reversed') +def list_reversed__ANY(space, w_list): + w_list.running_iter = W_SeqIterObject(space,w_list,-1,True) + return w_list.running_iter + register_all(vars(), globals()) # ____________________________________________________________ From ale at codespeak.net Mon Aug 8 20:31:00 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 8 Aug 2005 20:31:00 +0200 (CEST) Subject: [pypy-svn] r15789 - pypy/dist/lib-python Message-ID: <20050808183100.45C1527B41@code1.codespeak.net> Author: ale Date: Mon Aug 8 20:30:59 2005 New Revision: 15789 Modified: pypy/dist/lib-python/failure_list.txt Log: update Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Mon Aug 8 20:30:59 2005 @@ -7,11 +7,11 @@ multiple tests fail because from __future__ import division does not work (true division is never enabled) -test_iterlen (ale will work on this) +test_iterlen (ale will work on this) FIXED (finally) fails because len is not implemented for SeqIter (and other structures like generators (reversed) ) - + test_compiler fails because of "maximum recursion depth exceeded" From pedronis at codespeak.net Mon Aug 8 21:25:47 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 8 Aug 2005 21:25:47 +0200 (CEST) Subject: [pypy-svn] r15792 - in pypy/dist/pypy: rpython rpython/module rpython/module/test translator/c translator/c/src translator/c/test Message-ID: <20050808192547.408E427B3D@code1.codespeak.net> Author: pedronis Date: Mon Aug 8 21:25:41 2005 New Revision: 15792 Added: pypy/dist/pypy/rpython/module/ll_strtod.py (contents, props changed) pypy/dist/pypy/rpython/module/test/test_ll_strtod.py (contents, props changed) Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/rarithmetic.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: support for low-level wrapper around strtod, to be called by strutil Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Mon Aug 8 21:25:41 2005 @@ -120,3 +120,8 @@ s = ntpath.splitdrive(s)[1] return s != '' and s[0] in '/\\' ntpath.isabs = isabs + +# ___________________________________________________________ +# string->float helper +from pypy.rpython import rarithmetic +declare(rarithmetic.parts_to_float, float, 'll_strtod/parts_to_float') Added: pypy/dist/pypy/rpython/module/ll_strtod.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/module/ll_strtod.py Mon Aug 8 21:25:41 2005 @@ -0,0 +1,12 @@ +# string -> float helper +from pypy.rpython import rarithmetic +from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy + + +def ll_strtod_parts_to_float(sign, beforept, afterpt, exponent): + return rarithmetic.parts_to_float(from_rstr(sign), + from_rstr(beforept), + from_rstr(afterpt), + from_rstr(exponent)) + +ll_strtod_parts_to_float.suggested_primitive = True Added: pypy/dist/pypy/rpython/module/test/test_ll_strtod.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/module/test/test_ll_strtod.py Mon Aug 8 21:25:41 2005 @@ -0,0 +1,18 @@ + +from pypy.rpython.module.ll_strtod import ll_strtod_parts_to_float +from pypy.rpython.module.support import to_rstr + + +def test_it(): + data = [ + (("","1","","") , 1.0), + (("-","1","","") , -1.0), + (("-","1","5","") , -1.5), + (("-","1","5","2") , -1.5e2), + (("-","1","5","+2") , -1.5e2), + (("-","1","5","-2") , -1.5e-2), + ] + + for parts, val in data: + assert ll_strtod_parts_to_float(*map(to_rstr, parts)) == val + Modified: pypy/dist/pypy/rpython/rarithmetic.py ============================================================================== --- pypy/dist/pypy/rpython/rarithmetic.py (original) +++ pypy/dist/pypy/rpython/rarithmetic.py Mon Aug 8 21:25:41 2005 @@ -369,3 +369,12 @@ setup_typemap() del setup_typemap + +# string -> float helper + +def parts_to_float(sign, beforept, afterpt, exponent): + if not exponent: + exponent = '0' + return float("%s%s.%se%s" % (sign, beforept, afterpt, exponent)) + +# float -> string Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Mon Aug 8 21:25:41 2005 @@ -4,7 +4,7 @@ from pypy.rpython.rmodel import getfunctionptr from pypy.rpython.rstr import STR from pypy.rpython import rlist -from pypy.rpython.module import ll_os, ll_time, ll_math +from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod # table of functions hand-written in src/ll_*.h @@ -30,6 +30,8 @@ ll_math.ll_math_ldexp: 'LL_math_ldexp', ll_math.ll_math_modf: 'LL_math_modf', ll_math.ll_math_hypot: 'LL_math_hypot', + ll_strtod.ll_strtod_parts_to_float: + 'LL_strtod_parts_to_float', } #______________________________________________________ Modified: pypy/dist/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_include.h (original) +++ pypy/dist/pypy/translator/c/src/g_include.h Mon Aug 8 21:25:41 2005 @@ -35,6 +35,7 @@ # include "src/ll_os.h" # include "src/ll_time.h" # include "src/ll_math.h" +# include "src/ll_strtod.h" #endif #ifdef PYPY_STANDALONE Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Mon Aug 8 21:25:41 2005 @@ -214,3 +214,23 @@ res = fn() t1 = time.time() assert t0 <= res <= t1 + + +def test_rarith_parts_to_float(): + from pypy.rpython.rarithmetic import parts_to_float + def fn(sign, beforept, afterpt, exponent): + return parts_to_float(sign, beforept, afterpt, exponent) + + f = compile(fn, [str, str, str, str]) + + data = [ + (("","1","","") , 1.0), + (("-","1","","") , -1.0), + (("-","1","5","") , -1.5), + (("-","1","5","2") , -1.5e2), + (("-","1","5","+2") , -1.5e2), + (("-","1","5","-2") , -1.5e-2), + ] + + for parts, val in data: + assert f(*parts) == val From pedronis at codespeak.net Mon Aug 8 21:27:19 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 8 Aug 2005 21:27:19 +0200 (CEST) Subject: [pypy-svn] r15793 - pypy/dist/pypy/translator/c/src Message-ID: <20050808192719.12AD927B3D@code1.codespeak.net> Author: pedronis Date: Mon Aug 8 21:27:17 2005 New Revision: 15793 Added: pypy/dist/pypy/translator/c/src/ll_strtod.h (contents, props changed) Log: oops, forgot the header file Added: pypy/dist/pypy/translator/c/src/ll_strtod.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/ll_strtod.h Mon Aug 8 21:27:17 2005 @@ -0,0 +1,56 @@ +#include + +double LL_strtod_parts_to_float( + RPyString *sign, + RPyString *beforept, + RPyString *afterpt, + RPyString *exponent) +{ + char *fail_pos; + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + double x; + char *last; + char *expo = RPyString_AsString(exponent); + + if (*expo == '\0') { + expo = "0"; + } + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + int buf_size = RPyString_Size(sign) + + RPyString_Size(beforept) + + decimal_point_len + + RPyString_Size(afterpt) + + 1 /* e */ + + strlen(expo) + + 1 /* asciiz */ ; + + char *s = malloc(buf_size); + strcpy(s, RPyString_AsString(sign)); + strcat(s, RPyString_AsString(beforept)); + strcat(s, decimal_point); + strcat(s, RPyString_AsString(afterpt)); + strcat(s, "e"); + strcat(s, expo); + + last = s + (buf_size-1); + x = strtod(s, &fail_pos); + errno = 0; + free(s); + if (fail_pos > last) + fail_pos = last; + if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { + RPyRaiseSimpleException(PyExc_ValueError, "invalid float literal"); + return -1.0; + } + if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ + x = strtod(s, NULL); + errno = 0; + } + return x; +} From arigo at codespeak.net Mon Aug 8 21:49:55 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Aug 2005 21:49:55 +0200 (CEST) Subject: [pypy-svn] r15794 - pypy/dist/pypy/translator/c Message-ID: <20050808194955.89EB427B3E@code1.codespeak.net> Author: arigo Date: Mon Aug 8 21:49:53 2005 New Revision: 15794 Modified: pypy/dist/pypy/translator/c/funcgen.py Log: issue107 in-progress Prefix local variables with "l_". Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Mon Aug 8 21:49:53 2005 @@ -8,6 +8,7 @@ PyObjPtr = Ptr(PyObject) +LOCALVAR = 'l_%s' class FunctionCodeGenerator: """ @@ -53,7 +54,7 @@ self.lltypes[id(v)] = v, T, typename def argnames(self): - return [v.name for v in self.graph.getargs()] + return [LOCALVAR % v.name for v in self.graph.getargs()] def allvariables(self): return [v for v, T, typename in self.lltypes.values() @@ -83,7 +84,7 @@ if self.lltypemap(v) == Void and special_case_void: return '/* nothing */' else: - return v.name + return LOCALVAR % v.name elif isinstance(v, Constant): value = llvalue_from_constant(v) if value is None and not special_case_void: @@ -122,7 +123,7 @@ name = v.name if name not in seen: seen[name] = True - result = cdecl(self.lltypename(v), name) + ';' + result = cdecl(self.lltypename(v), LOCALVAR % name) + ';' if self.lltypemap(v) == Void: result = '/*%s*/' % result result_by_name.append((v._name, result)) @@ -524,8 +525,8 @@ def cincref(self, v): T = self.lltypemap(v) - return self.db.cincrefstmt(v.name, T) + return self.db.cincrefstmt(LOCALVAR % v.name, T) def cdecref(self, v, expr=None): T = self.lltypemap(v) - return self.db.cdecrefstmt(expr or v.name, T) + return self.db.cdecrefstmt(expr or (LOCALVAR % v.name), T) From arigo at codespeak.net Mon Aug 8 22:22:42 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 8 Aug 2005 22:22:42 +0200 (CEST) Subject: [pypy-svn] r15795 - in pypy/dist/pypy/translator/c: . src Message-ID: <20050808202242.6120027B3F@code1.codespeak.net> Author: arigo Date: Mon Aug 8 22:22:37 2005 New Revision: 15795 Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/char.h pypy/dist/pypy/translator/c/src/exception.h pypy/dist/pypy/translator/c/src/float.h pypy/dist/pypy/translator/c/src/int.h pypy/dist/pypy/translator/c/src/mem.h pypy/dist/pypy/translator/c/src/module.h pypy/dist/pypy/translator/c/src/pyobj.h pypy/dist/pypy/translator/c/src/support.h pypy/dist/pypy/translator/c/src/trace.h pypy/dist/pypy/translator/c/src/unichar.h Log: issue107 testing Normalizing the macro call conventions: now the macros no longer contain the final ';', which is traditional in C. Previously, some macros didn't require an extra ';' after the call -- typically the OP_* and FAIL* macros. Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Mon Aug 8 22:22:37 2005 @@ -207,7 +207,7 @@ lst = [self.expr(v) for v in op.args] lst.append(self.expr(op.result)) lst.append(err) - yield '%s(%s)' % (macro, ', '.join(lst)) + yield '%s(%s);' % (macro, ', '.join(lst)) to_release.append(op.result) err_reachable = False @@ -326,48 +326,48 @@ args = [self.expr(v) for v in op.args] r = self.expr(op.result) if len(args) == 0: - return 'OP_NEWLIST0(%s, %s)' % (r, err) + return 'OP_NEWLIST0(%s, %s);' % (r, err) else: args.insert(0, '%d' % len(args)) - return 'OP_NEWLIST((%s), %s, %s)' % (', '.join(args), r, err) + return 'OP_NEWLIST((%s), %s, %s);' % (', '.join(args), r, err) def OP_NEWDICT(self, op, err): args = [self.expr(v) for v in op.args] r = self.expr(op.result) if len(args) == 0: - return 'OP_NEWDICT0(%s, %s)' % (r, err) + return 'OP_NEWDICT0(%s, %s);' % (r, err) else: assert len(args) % 2 == 0 args.insert(0, '%d' % (len(args)//2)) - return 'OP_NEWDICT((%s), %s, %s)' % (', '.join(args), r, err) + return 'OP_NEWDICT((%s), %s, %s);' % (', '.join(args), r, err) def OP_NEWTUPLE(self, op, err): args = [self.expr(v) for v in op.args] r = self.expr(op.result) args.insert(0, '%d' % len(args)) - return 'OP_NEWTUPLE((%s), %s, %s)' % (', '.join(args), r, err) + return 'OP_NEWTUPLE((%s), %s, %s);' % (', '.join(args), r, err) def OP_SIMPLE_CALL(self, op, err): args = [self.expr(v) for v in op.args] r = self.expr(op.result) args.append('NULL') - return 'OP_SIMPLE_CALL((%s), %s, %s)' % (', '.join(args), r, err) + return 'OP_SIMPLE_CALL((%s), %s, %s);' % (', '.join(args), r, err) def OP_CALL_ARGS(self, op, err): args = [self.expr(v) for v in op.args] r = self.expr(op.result) - return 'OP_CALL_ARGS((%s), %s, %s)' % (', '.join(args), r, err) + return 'OP_CALL_ARGS((%s), %s, %s);' % (', '.join(args), r, err) def OP_DIRECT_CALL(self, op, err): # skip 'void' arguments args = [self.expr(v) for v in op.args if self.lltypemap(v) != Void] if self.lltypemap(op.result) == Void: # skip assignment of 'void' return value - return '%s(%s); if (RPyExceptionOccurred()) FAIL(%s)' % ( + return '%s(%s); if (RPyExceptionOccurred()) FAIL(%s);' % ( args[0], ', '.join(args[1:]), err) else: r = self.expr(op.result) - return '%s = %s(%s); if (RPyExceptionOccurred()) FAIL(%s)' % ( + return '%s = %s(%s); if (RPyExceptionOccurred()) FAIL(%s);' % ( r, args[0], ', '.join(args[1:]), err) # low-level operations @@ -463,9 +463,9 @@ TYPE = self.lltypemap(op.result).TO typename = self.db.gettype(TYPE) eresult = self.expr(op.result) - result = ['OP_ZERO_MALLOC(sizeof(%s), %s, %s)' % (cdecl(typename, ''), - eresult, - err), + result = ['OP_ZERO_MALLOC(sizeof(%s), %s, %s);' % (cdecl(typename, ''), + eresult, + err), '%s->%s = 1;' % (eresult, self.db.gettypedefnode(TYPE).refcount), ] @@ -490,9 +490,9 @@ size = 'sizeof(%s)+((%s-1)*sizeof(%s))' % (cdecl(typename, ''), elength, cdecl(itemtypename, '')) - result = ['OP_ZERO_MALLOC(%s, %s, %s)' % (size, - eresult, - err), + result = ['OP_ZERO_MALLOC(%s, %s, %s);' % (size, + eresult, + err), '%s->%s = %s;' % (eresult, lenfld, elength), '%s->%s = 1;' % (eresult, Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Mon Aug 8 22:22:37 2005 @@ -303,7 +303,7 @@ print >> f print >> f, 'MODULE_INITFUNC(%s)' % modulename print >> f, '{' - print >> f, '\tSETUP_MODULE(%s)' % modulename + print >> f, '\tSETUP_MODULE(%s);' % modulename for publicname, pyobjptr in exports.items(): # some fishing needed to find the name of the obj pyobjnode = database.containernodes[pyobjptr._obj] Modified: pypy/dist/pypy/translator/c/src/char.h ============================================================================== --- pypy/dist/pypy/translator/c/src/char.h (original) +++ pypy/dist/pypy/translator/c/src/char.h Mon Aug 8 22:22:37 2005 @@ -6,10 +6,10 @@ /*** binary operations ***/ -#define OP_CHAR_EQ(x,y,r,err) r = ((x) == (y)); -#define OP_CHAR_NE(x,y,r,err) r = ((x) != (y)); -#define OP_CHAR_LE(x,y,r,err) r = ((unsigned char)(x) <= (unsigned char)(y)); -#define OP_CHAR_GT(x,y,r,err) r = ((unsigned char)(x) > (unsigned char)(y)); -#define OP_CHAR_LT(x,y,r,err) r = ((unsigned char)(x) < (unsigned char)(y)); -#define OP_CHAR_GE(x,y,r,err) r = ((unsigned char)(x) >= (unsigned char)(y)); +#define OP_CHAR_EQ(x,y,r,err) r = ((x) == (y)) +#define OP_CHAR_NE(x,y,r,err) r = ((x) != (y)) +#define OP_CHAR_LE(x,y,r,err) r = ((unsigned char)(x) <= (unsigned char)(y)) +#define OP_CHAR_GT(x,y,r,err) r = ((unsigned char)(x) > (unsigned char)(y)) +#define OP_CHAR_LT(x,y,r,err) r = ((unsigned char)(x) < (unsigned char)(y)) +#define OP_CHAR_GE(x,y,r,err) r = ((unsigned char)(x) >= (unsigned char)(y)) Modified: pypy/dist/pypy/translator/c/src/exception.h ============================================================================== --- pypy/dist/pypy/translator/c/src/exception.h (original) +++ pypy/dist/pypy/translator/c/src/exception.h Mon Aug 8 22:22:37 2005 @@ -65,7 +65,7 @@ _RPyConvertExceptionToCPython(); \ vanishing = rpython_exc_value; \ rpython_exc_type = NULL; \ - rpython_exc_value = NULL; + rpython_exc_value = NULL #endif /* !PYPY_STANDALONE */ Modified: pypy/dist/pypy/translator/c/src/float.h ============================================================================== --- pypy/dist/pypy/translator/c/src/float.h (original) +++ pypy/dist/pypy/translator/c/src/float.h Mon Aug 8 22:22:37 2005 @@ -6,35 +6,35 @@ /*** unary operations ***/ #define OP_FLOAT_IS_TRUE(x,r,err) OP_FLOAT_NE(x,0.0,r,err) -#define OP_FLOAT_NEG(x,r,err) r = -x; -#define OP_FLOAT_ABS(x,r,err) r = fabs(x); +#define OP_FLOAT_NEG(x,r,err) r = -x +#define OP_FLOAT_ABS(x,r,err) r = fabs(x) /*** binary operations ***/ -#define OP_FLOAT_EQ(x,y,r,err) r = (x == y); -#define OP_FLOAT_NE(x,y,r,err) r = (x != y); -#define OP_FLOAT_LE(x,y,r,err) r = (x <= y); -#define OP_FLOAT_GT(x,y,r,err) r = (x > y); -#define OP_FLOAT_LT(x,y,r,err) r = (x < y); -#define OP_FLOAT_GE(x,y,r,err) r = (x >= y); +#define OP_FLOAT_EQ(x,y,r,err) r = (x == y) +#define OP_FLOAT_NE(x,y,r,err) r = (x != y) +#define OP_FLOAT_LE(x,y,r,err) r = (x <= y) +#define OP_FLOAT_GT(x,y,r,err) r = (x > y) +#define OP_FLOAT_LT(x,y,r,err) r = (x < y) +#define OP_FLOAT_GE(x,y,r,err) r = (x >= y) #define OP_FLOAT_CMP(x,y,r,err) \ r = ((x > y) - (x < y)) /* addition, subtraction */ -#define OP_FLOAT_ADD(x,y,r,err) r = x + y; -#define OP_FLOAT_SUB(x,y,r,err) r = x - y; -#define OP_FLOAT_MUL(x,y,r,err) r = x * y; -#define OP_FLOAT_DIV(x,y,r,err) r = x / y; +#define OP_FLOAT_ADD(x,y,r,err) r = x + y +#define OP_FLOAT_SUB(x,y,r,err) r = x - y +#define OP_FLOAT_MUL(x,y,r,err) r = x * y +#define OP_FLOAT_DIV(x,y,r,err) r = x / y #define OP_FLOAT_TRUEDIV(x,y,r,err) OP_FLOAT_DIV(x,y,r,err) -#define OP_FLOAT_MOD(x,y,r,err) r = fmod(x, y); -#define OP_FLOAT_POW(x,y,r,err) r = pow(x, y); +#define OP_FLOAT_MOD(x,y,r,err) r = fmod(x, y) +#define OP_FLOAT_POW(x,y,r,err) r = pow(x, y) /*** conversions ***/ -#define OP_CAST_FLOAT_TO_INT(x,r,err) r = (long)(x); -#define OP_CAST_FLOAT_TO_UINT(x,r,err) r = (unsigned long)(x); -#define OP_CAST_INT_TO_FLOAT(x,r,err) r = (double)(x); -#define OP_CAST_UINT_TO_FLOAT(x,r,err) r = (double)(x); -#define OP_CAST_BOOL_TO_FLOAT(x,r,err) r = (double)(x); +#define OP_CAST_FLOAT_TO_INT(x,r,err) r = (long)(x) +#define OP_CAST_FLOAT_TO_UINT(x,r,err) r = (unsigned long)(x) +#define OP_CAST_INT_TO_FLOAT(x,r,err) r = (double)(x) +#define OP_CAST_UINT_TO_FLOAT(x,r,err) r = (double)(x) +#define OP_CAST_BOOL_TO_FLOAT(x,r,err) r = (double)(x) Modified: pypy/dist/pypy/translator/c/src/int.h ============================================================================== --- pypy/dist/pypy/translator/c/src/int.h (original) +++ pypy/dist/pypy/translator/c/src/int.h Mon Aug 8 22:22:37 2005 @@ -6,54 +6,54 @@ #define OP_INT_IS_TRUE(x,r,err) OP_INT_NE(x,0,r,err) -#define OP_INT_INVERT(x,r,err) r = ~((x)); +#define OP_INT_INVERT(x,r,err) r = ~((x)) -#define OP_INT_POS(x,r,err) r = x; +#define OP_INT_POS(x,r,err) r = x -#define OP_INT_NEG(x,r,err) r = -(x); +#define OP_INT_NEG(x,r,err) r = -(x) #define OP_INT_NEG_OVF(x,r,err) \ - OP_INT_NEG(x,r,err) \ + OP_INT_NEG(x,r,err); \ if ((x) >= 0 || (x) != -(x)); \ else FAIL_OVF(err, "integer negate") -#define OP_INT_ABS(x,r,err) r = (x) >= 0 ? x : -(x); -#define OP_UINT_ABS(x,r,err) r = (x); +#define OP_INT_ABS(x,r,err) r = (x) >= 0 ? x : -(x) +#define OP_UINT_ABS(x,r,err) r = (x) #define OP_INT_ABS_OVF(x,r,err) \ - OP_INT_ABS(x,r,err) \ + OP_INT_ABS(x,r,err); \ if ((x) >= 0 || (x) != -(x)); \ else FAIL_OVF(err, "integer absolute") /*** binary operations ***/ -#define OP_INT_EQ(x,y,r,err) r = ((x) == (y)); -#define OP_INT_NE(x,y,r,err) r = ((x) != (y)); -#define OP_INT_LE(x,y,r,err) r = ((x) <= (y)); -#define OP_INT_GT(x,y,r,err) r = ((x) > (y)); -#define OP_INT_LT(x,y,r,err) r = ((x) < (y)); -#define OP_INT_GE(x,y,r,err) r = ((x) >= (y)); +#define OP_INT_EQ(x,y,r,err) r = ((x) == (y)) +#define OP_INT_NE(x,y,r,err) r = ((x) != (y)) +#define OP_INT_LE(x,y,r,err) r = ((x) <= (y)) +#define OP_INT_GT(x,y,r,err) r = ((x) > (y)) +#define OP_INT_LT(x,y,r,err) r = ((x) < (y)) +#define OP_INT_GE(x,y,r,err) r = ((x) >= (y)) #define OP_INT_CMP(x,y,r,err) \ r = (((x) > (y)) - ((x) < (y))) /* addition, subtraction */ -#define OP_INT_ADD(x,y,r,err) r = (x) + (y); +#define OP_INT_ADD(x,y,r,err) r = (x) + (y) #define OP_INT_ADD_OVF(x,y,r,err) \ - OP_INT_ADD(x,y,r,err) \ + OP_INT_ADD(x,y,r,err); \ if ((r^(x)) >= 0 || (r^(y)) >= 0); \ else FAIL_OVF(err, "integer addition") -#define OP_INT_SUB(x,y,r,err) r = (x) - (y); +#define OP_INT_SUB(x,y,r,err) r = (x) - (y) #define OP_INT_SUB_OVF(x,y,r,err) \ - OP_INT_SUB(x,y,r,err) \ + OP_INT_SUB(x,y,r,err); \ if ((r^(x)) >= 0 || (r^~(y)) >= 0); \ else FAIL_OVF(err, "integer subtraction") -#define OP_INT_MUL(x,y,r,err) r = (x) * (y); +#define OP_INT_MUL(x,y,r,err) r = (x) * (y) #ifndef HAVE_LONG_LONG @@ -68,7 +68,7 @@ PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y); \ r = lr; \ if ((PY_LONG_LONG)r == lr); \ - else FAIL_OVF(err, "integer multiplication") \ + else FAIL_OVF(err, "integer multiplication"); \ } #endif @@ -76,96 +76,96 @@ /* NB. shifting has same limitations as C: the shift count must be >= 0 and < LONG_BITS. */ -#define OP_INT_RSHIFT(x,y,r,err) r = Py_ARITHMETIC_RIGHT_SHIFT(long, x, y); -#define OP_UINT_RSHIFT(x,y,r,err) r = (x) >> (y); +#define OP_INT_RSHIFT(x,y,r,err) r = Py_ARITHMETIC_RIGHT_SHIFT(long, x, y) +#define OP_UINT_RSHIFT(x,y,r,err) r = (x) >> (y) -#define OP_INT_LSHIFT(x,y,r,err) r = (x) << (y); -#define OP_UINT_LSHIFT(x,y,r,err) r = (x) << (y); +#define OP_INT_LSHIFT(x,y,r,err) r = (x) << (y) +#define OP_UINT_LSHIFT(x,y,r,err) r = (x) << (y) #define OP_INT_LSHIFT_OVF(x,y,r,err) \ - OP_INT_LSHIFT(x,y,r,err) \ + OP_INT_LSHIFT(x,y,r,err); \ if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \ FAIL_OVF(err, "x<= 0) { OP_INT_RSHIFT(x,y,r,err) } \ + if ((y) >= 0) { OP_INT_RSHIFT(x,y,r,err); } \ else FAIL_VAL(err, "negative shift count") #define OP_INT_LSHIFT_VAL(x,y,r,err) \ - if ((y) >= 0) { OP_INT_LSHIFT(x,y,r,err) } \ + if ((y) >= 0) { OP_INT_LSHIFT(x,y,r,err); } \ else FAIL_VAL(err, "negative shift count") #define OP_INT_LSHIFT_OVF_VAL(x,y,r,err) \ - if ((y) >= 0) { OP_INT_LSHIFT_OVF(x,y,r,err) } \ + if ((y) >= 0) { OP_INT_LSHIFT_OVF(x,y,r,err); } \ else FAIL_VAL(err, "negative shift count") /* floor division */ -#define OP_INT_FLOORDIV(x,y,r,err) r = op_divmod_adj(x, y, NULL); -#define OP_UINT_FLOORDIV(x,y,r,err) r = (x) / (y); +#define OP_INT_FLOORDIV(x,y,r,err) r = op_divmod_adj(x, y, NULL) +#define OP_UINT_FLOORDIV(x,y,r,err) r = (x) / (y) #define OP_INT_FLOORDIV_OVF(x,y,r,err) \ if ((y) == -1 && (x) < 0 && ((unsigned long)(x) << 1) == 0) \ - FAIL_OVF(err, "integer division") \ + FAIL_OVF(err, "integer division"); \ OP_INT_FLOORDIV(x,y,r,err) #define OP_INT_FLOORDIV_ZER(x,y,r,err) \ - if ((y)) { OP_INT_FLOORDIV(x,y,r,err) } \ + if ((y)) { OP_INT_FLOORDIV(x,y,r,err); } \ else FAIL_ZER(err, "integer division") #define OP_UINT_FLOORDIV_ZER(x,y,r,err) \ - if ((y)) { OP_UINT_FLOORDIV(x,y,r,err) } \ + if ((y)) { OP_UINT_FLOORDIV(x,y,r,err); } \ else FAIL_ZER(err, "unsigned integer division") #define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \ - if ((y)) { OP_INT_FLOORDIV_OVF(x,y,r,err) } \ + if ((y)) { OP_INT_FLOORDIV_OVF(x,y,r,err); } \ else FAIL_ZER(err, "integer division") /* modulus */ -#define OP_INT_MOD(x,y,r,err) op_divmod_adj(x, y, &r); -#define OP_UINT_MOD(x,y,r,err) r = (x) % (y); +#define OP_INT_MOD(x,y,r,err) op_divmod_adj(x, y, &r) +#define OP_UINT_MOD(x,y,r,err) r = (x) % (y) #define OP_INT_MOD_OVF(x,y,r,err) \ if ((y) == -1 && (x) < 0 && ((unsigned long)(x) << 1) == 0) \ - FAIL_OVF(err, "integer modulo") \ - OP_INT_MOD(x,y,r,err); + FAIL_OVF(err, "integer modulo"); \ + OP_INT_MOD(x,y,r,err) #define OP_INT_MOD_ZER(x,y,r,err) \ - if ((y)) { OP_INT_MOD(x,y,r,err) } \ + if ((y)) { OP_INT_MOD(x,y,r,err); } \ else FAIL_ZER(err, "integer modulo") #define OP_UINT_MOD_ZER(x,y,r,err) \ - if ((y)) { OP_UINT_MOD(x,y,r,err) } \ + if ((y)) { OP_UINT_MOD(x,y,r,err); } \ else FAIL_ZER(err, "unsigned integer modulo") #define OP_INT_MOD_OVF_ZER(x,y,r,err) \ - if ((y)) { OP_INT_MOD_OVF(x,y,r,err) } \ + if ((y)) { OP_INT_MOD_OVF(x,y,r,err); } \ else FAIL_ZER(err, "integer modulo") /* bit operations */ -#define OP_INT_AND(x,y,r,err) r = (x) & (y); -#define OP_INT_OR( x,y,r,err) r = (x) | (y); -#define OP_INT_XOR(x,y,r,err) r = (x) ^ (y); +#define OP_INT_AND(x,y,r,err) r = (x) & (y) +#define OP_INT_OR( x,y,r,err) r = (x) | (y) +#define OP_INT_XOR(x,y,r,err) r = (x) ^ (y) /*** conversions ***/ -#define OP_CAST_BOOL_TO_INT(x,r,err) r = (long)(x); -#define OP_CAST_BOOL_TO_UINT(x,r,err) r = (unsigned long)(x); -#define OP_CAST_UINT_TO_INT(x,r,err) r = (long)(x); -#define OP_CAST_INT_TO_UINT(x,r,err) r = (unsigned long)(x); -#define OP_CAST_CHAR_TO_INT(x,r,err) r = (long)((unsigned char)(x)); -#define OP_CAST_INT_TO_CHAR(x,r,err) r = (char)(x); -#define OP_CAST_PTR_TO_INT(x,r,err) r = (long)(x); /* XXX */ +#define OP_CAST_BOOL_TO_INT(x,r,err) r = (long)(x) +#define OP_CAST_BOOL_TO_UINT(x,r,err) r = (unsigned long)(x) +#define OP_CAST_UINT_TO_INT(x,r,err) r = (long)(x) +#define OP_CAST_INT_TO_UINT(x,r,err) r = (unsigned long)(x) +#define OP_CAST_CHAR_TO_INT(x,r,err) r = (long)((unsigned char)(x)) +#define OP_CAST_INT_TO_CHAR(x,r,err) r = (char)(x) +#define OP_CAST_PTR_TO_INT(x,r,err) r = (long)(x) /* XXX */ -#define OP_CAST_UNICHAR_TO_INT(x,r,err) r = (long)((unsigned long)(x)); /*?*/ -#define OP_CAST_INT_TO_UNICHAR(x,r,err) r = (unsigned int)(x); +#define OP_CAST_UNICHAR_TO_INT(x,r,err) r = (long)((unsigned long)(x)) /*?*/ +#define OP_CAST_INT_TO_UNICHAR(x,r,err) r = (unsigned int)(x) /* bool operations */ -#define OP_BOOL_NOT(x, r, err) r = !(x); +#define OP_BOOL_NOT(x, r, err) r = !(x) /* _________________ certain implementations __________________ */ Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Mon Aug 8 22:22:37 2005 @@ -10,12 +10,12 @@ #define OP_ZERO_MALLOC(size, r, err) { \ r = (void*) PyObject_Malloc(size); \ - if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory")\ + if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory");\ memset((void*) r, 0, size); \ - COUNT_MALLOC \ + COUNT_MALLOC; \ } -#define OP_FREE(p) { PyObject_Free(p); COUNT_FREE } +#define OP_FREE(p) { PyObject_Free(p); COUNT_FREE; } /*------------------------------------------------------------*/ @@ -31,8 +31,8 @@ static int count_mallocs=0, count_frees=0; -#define COUNT_MALLOC count_mallocs++; -#define COUNT_FREE count_frees++; +#define COUNT_MALLOC count_mallocs++ +#define COUNT_FREE count_frees++ PyObject* malloc_counters(PyObject* self, PyObject* args) { Modified: pypy/dist/pypy/translator/c/src/module.h ============================================================================== --- pypy/dist/pypy/translator/c/src/module.h (original) +++ pypy/dist/pypy/translator/c/src/module.h Mon Aug 8 22:22:37 2005 @@ -34,7 +34,7 @@ if (setup_initcode(frozen_initcode, FROZEN_INITCODE_SIZE) < 0) \ return; \ if (setup_globalobjects(globalobjectdefs) < 0) \ - return; + return /*** table of global objects ***/ Modified: pypy/dist/pypy/translator/c/src/pyobj.h ============================================================================== --- pypy/dist/pypy/translator/c/src/pyobj.h (original) +++ pypy/dist/pypy/translator/c/src/pyobj.h Mon Aug 8 22:22:37 2005 @@ -6,9 +6,7 @@ #define op_bool(r,err,what) { \ int _retval = what; \ - if (_retval < 0) { \ - CFAIL(err) \ - } \ + if (_retval < 0) CFAIL(err); \ r = PyBool_FromLong(_retval); \ } @@ -28,9 +26,7 @@ #define OP_LEN(x,r,err) { \ int _retval = PyObject_Size(x); \ - if (_retval < 0) { \ - CFAIL(err) \ - } \ + if (_retval < 0) CFAIL(err); \ r = PyInt_FromLong(_retval); \ } #define OP_NEG(x,r,err) if (!(r=PyNumber_Negative(x))) CFAIL(err) @@ -80,20 +76,20 @@ #define OP_INPLACE_XOR(x,y,r,err) if (!(r=PyNumber_InPlaceXor(x,y))) \ CFAIL(err) -#define OP_GETITEM(x,y,r,err) if (!(r=PyObject_GetItem1(x,y))) CFAIL(err) -#define OP_SETITEM(x,y,z,r,err) if ((PyObject_SetItem1(x,y,z))<0) CFAIL(err) \ - r=Py_None; Py_INCREF(r); -#define OP_DELITEM(x,y,r,err) if ((PyObject_DelItem(x,y))<0) CFAIL(err) \ - r=Py_None; Py_INCREF(r); +#define OP_GETITEM(x,y,r,err) if (!(r=PyObject_GetItem1(x,y))) CFAIL(err) +#define OP_SETITEM(x,y,z,r,err) if ((PyObject_SetItem1(x,y,z))<0) CFAIL(err);\ + r=Py_None; Py_INCREF(r) +#define OP_DELITEM(x,y,r,err) if ((PyObject_DelItem(x,y))<0) CFAIL(err);\ + r=Py_None; Py_INCREF(r) #define OP_CONTAINS(x,y,r,err) op_bool(r,err,(PySequence_Contains(x,y))) -#define OP_GETATTR(x,y,r,err) if (!(r=PyObject_GetAttr(x,y))) CFAIL(err) -#define OP_SETATTR(x,y,z,r,err) if ((PyObject_SetAttr(x,y,z))<0) CFAIL(err) \ - r=Py_None; Py_INCREF(r); -#define OP_DELATTR(x,y,r,err) if ((PyObject_SetAttr(x,y,NULL))<0)CFAIL(err) \ - r=Py_None; Py_INCREF(r); +#define OP_GETATTR(x,y,r,err) if (!(r=PyObject_GetAttr(x,y))) CFAIL(err) +#define OP_SETATTR(x,y,z,r,err) if ((PyObject_SetAttr(x,y,z))<0) CFAIL(err);\ + r=Py_None; Py_INCREF(r) +#define OP_DELATTR(x,y,r,err) if ((PyObject_SetAttr(x,y,NULL))<0)CFAIL(err);\ + r=Py_None; Py_INCREF(r) -#define OP_NEWSLICE(x,y,z,r,err) if (!(r=PySlice_New(x,y,z))) CFAIL(err) +#define OP_NEWSLICE(x,y,z,r,err) if (!(r=PySlice_New(x,y,z))) CFAIL(err) #define OP_GETSLICE(x,y,z,r,err) { \ PyObject *__yo = y, *__zo = z; \ @@ -102,14 +98,14 @@ if (__zo == Py_None) __zo = NULL; \ if (!_PyEval_SliceIndex(__yo, &__y) || \ !_PyEval_SliceIndex(__zo, &__z) || \ - !(r=PySequence_GetSlice(x, __y, __z))) CFAIL(err) \ + !(r=PySequence_GetSlice(x, __y, __z))) CFAIL(err); \ } #define OP_ALLOC_AND_SET(x,y,r,err) { \ /* XXX check for long/int overflow */ \ int __i, __x = PyInt_AsLong(x); \ - if (PyErr_Occurred()) CFAIL(err) \ - if (!(r = PyList_New(__x))) CFAIL(err) \ + if (PyErr_Occurred()) CFAIL(err); \ + if (!(r = PyList_New(__x))) CFAIL(err); \ for (__i=0; __i<__x; __i++) { \ Py_INCREF(y); \ PyList_SET_ITEM(r, __i, y); \ @@ -119,7 +115,7 @@ #define OP_ITER(x,r,err) if (!(r=PyObject_GetIter(x))) CFAIL(err) #define OP_NEXT(x,r,err) if (!(r=PyIter_Next(x))) { \ if (!PyErr_Occurred()) PyErr_SetNone(PyExc_StopIteration); \ - CFAIL(err) \ + CFAIL(err); \ } #define OP_STR(x,r,err) if (!(r=PyObject_Str(x))) CFAIL(err) @@ -127,21 +123,21 @@ #define OP_ORD(s,r,err) { \ char *__c = PyString_AsString(s); \ int __len; \ - if ( !__c) CFAIL(err) \ + if ( !__c) CFAIL(err); \ if ((__len = PyString_GET_SIZE(s)) != 1) { \ PyErr_Format(PyExc_TypeError, \ "ord() expected a character, but string of length %d found", \ __len); \ - CFAIL(err) \ + CFAIL(err); \ } \ if (!(r = PyInt_FromLong((unsigned char)(__c[0])))) \ - CFAIL(err) \ + CFAIL(err); \ } #define OP_ID(x,r,err) if (!(r=PyLong_FromVoidPtr(x))) CFAIL(err) #define OP_HASH(x,r,err) { \ long __hash = PyObject_Hash(x); \ - if (__hash == -1 && PyErr_Occurred()) CFAIL(err) \ - if (!(r = PyInt_FromLong(__hash))) CFAIL(err) \ + if (__hash == -1 && PyErr_Occurred()) CFAIL(err); \ + if (!(r = PyInt_FromLong(__hash))) CFAIL(err); \ } #define OP_HEX(x,r,err) { \ @@ -150,9 +146,9 @@ __nb->nb_hex == NULL) { \ PyErr_SetString(PyExc_TypeError, \ "hex() argument can't be converted to hex"); \ - CFAIL(err) \ + CFAIL(err); \ } \ - if (!(r = (*__nb->nb_hex)(x))) CFAIL(err) \ + if (!(r = (*__nb->nb_hex)(x))) CFAIL(err); \ } #define OP_OCT(x,r,err) { \ PyNumberMethods *__nb; \ @@ -160,26 +156,26 @@ __nb->nb_oct == NULL) { \ PyErr_SetString(PyExc_TypeError, \ "oct() argument can't be converted to oct"); \ - CFAIL(err) \ + CFAIL(err); \ } \ - if (!(r = (*__nb->nb_oct)(x))) CFAIL(err) \ + if (!(r = (*__nb->nb_oct)(x))) CFAIL(err); \ } #define OP_INT(x,r,err) { \ long __val = PyInt_AsLong(x); \ - if (__val == -1 && PyErr_Occurred()) CFAIL(err) \ - if (!(r = PyInt_FromLong(__val))) CFAIL (err) \ + if (__val == -1 && PyErr_Occurred()) CFAIL(err); \ + if (!(r = PyInt_FromLong(__val))) CFAIL (err); \ } #define OP_FLOAT(x,r,err) { \ double __val = PyFloat_AsDouble(x); \ - if (PyErr_Occurred()) CFAIL(err) \ - if (!(r = PyFloat_FromDouble(__val))) CFAIL (err) \ + if (PyErr_Occurred()) CFAIL(err); \ + if (!(r = PyFloat_FromDouble(__val))) CFAIL (err); \ } #define OP_CMP(x,y,r,err) { \ int __val = PyObject_Compare(x, y); \ - if (PyErr_Occurred()) CFAIL(err) \ - if (!(r = PyInt_FromLong(__val))) CFAIL (err) \ + if (PyErr_Occurred()) CFAIL(err); \ + if (!(r = PyInt_FromLong(__val))) CFAIL (err); \ } Modified: pypy/dist/pypy/translator/c/src/support.h ============================================================================== --- pypy/dist/pypy/translator/c/src/support.h (original) +++ pypy/dist/pypy/translator/c/src/support.h Mon Aug 8 22:22:37 2005 @@ -12,12 +12,12 @@ #define FAIL_EXCEPTION(err, exc, msg) \ { \ RPyRaiseSimpleException(exc, msg); \ - FAIL(err) \ + FAIL(err); \ } #define FAIL_OVF(err, msg) FAIL_EXCEPTION(err, PyExc_OverflowError, msg) #define FAIL_VAL(err, msg) FAIL_EXCEPTION(err, PyExc_ValueError, msg) #define FAIL_ZER(err, msg) FAIL_EXCEPTION(err, PyExc_ZeroDivisionError, msg) -#define CFAIL(err) { RPyConvertExceptionFromCPython(); FAIL(err) } +#define CFAIL(err) { RPyConvertExceptionFromCPython(); FAIL(err); } #ifndef PYPY_STANDALONE Modified: pypy/dist/pypy/translator/c/src/trace.h ============================================================================== --- pypy/dist/pypy/translator/c/src/trace.h (original) +++ pypy/dist/pypy/translator/c/src/trace.h Mon Aug 8 22:22:37 2005 @@ -32,11 +32,7 @@ #else /* !defined(USE_CALL_TRACE) */ -#define FAIL(err) { goto err; } - -#define ERR_DECREF(arg) { Py_DECREF(arg); } - -#define FUNCTION_RETURN(rval) return rval; +#define FAIL(err) goto err #endif /* defined(USE_CALL_TRACE) */ Modified: pypy/dist/pypy/translator/c/src/unichar.h ============================================================================== --- pypy/dist/pypy/translator/c/src/unichar.h (original) +++ pypy/dist/pypy/translator/c/src/unichar.h Mon Aug 8 22:22:37 2005 @@ -6,6 +6,6 @@ /*** binary operations ***/ /* typedef unsigned pypy_unichar; */ -#define OP_UNICHAR_EQ(x,y,r,err) r = ((x) == (y)); -#define OP_UNICHAR_NE(x,y,r,err) r = ((x) != (y)); +#define OP_UNICHAR_EQ(x,y,r,err) r = ((x) == (y)) +#define OP_UNICHAR_NE(x,y,r,err) r = ((x) != (y)) From pedronis at codespeak.net Tue Aug 9 01:24:26 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 9 Aug 2005 01:24:26 +0200 (CEST) Subject: [pypy-svn] r15797 - in pypy/dist/pypy: rpython rpython/module rpython/module/test translator/c translator/c/src translator/c/test Message-ID: <20050808232426.0D38927B3D@code1.codespeak.net> Author: pedronis Date: Tue Aug 9 01:24:23 2005 New Revision: 15797 Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_strtod.py pypy/dist/pypy/rpython/module/test/test_ll_strtod.py pypy/dist/pypy/rpython/rarithmetic.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_strtod.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: low-level float->string helper formatd. Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Tue Aug 9 01:24:23 2005 @@ -125,3 +125,5 @@ # string->float helper from pypy.rpython import rarithmetic declare(rarithmetic.parts_to_float, float, 'll_strtod/parts_to_float') +# float->string helper +declare(rarithmetic.formatd, str, 'll_strtod/formatd') Modified: pypy/dist/pypy/rpython/module/ll_strtod.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_strtod.py (original) +++ pypy/dist/pypy/rpython/module/ll_strtod.py Tue Aug 9 01:24:23 2005 @@ -8,5 +8,8 @@ from_rstr(beforept), from_rstr(afterpt), from_rstr(exponent)) - ll_strtod_parts_to_float.suggested_primitive = True + +def ll_strtod_formatd(fmt, x): + return to_rstr(rarithmetic.formatd(from_rstr(fmt), x)) +ll_strtod_formatd.suggested_primitive = True Modified: pypy/dist/pypy/rpython/module/test/test_ll_strtod.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_strtod.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_strtod.py Tue Aug 9 01:24:23 2005 @@ -1,9 +1,9 @@ -from pypy.rpython.module.ll_strtod import ll_strtod_parts_to_float -from pypy.rpython.module.support import to_rstr +from pypy.rpython.module.ll_strtod import ll_strtod_parts_to_float, ll_strtod_formatd +from pypy.rpython.module.support import to_rstr, from_rstr -def test_it(): +def test_parts_to_float(): data = [ (("","1","","") , 1.0), (("-","1","","") , -1.0), @@ -16,3 +16,7 @@ for parts, val in data: assert ll_strtod_parts_to_float(*map(to_rstr, parts)) == val + +def test_formatd(): + res = ll_strtod_formatd(to_rstr("%.2f"), 1.5) + assert from_rstr(res) == "1.50" Modified: pypy/dist/pypy/rpython/rarithmetic.py ============================================================================== --- pypy/dist/pypy/rpython/rarithmetic.py (original) +++ pypy/dist/pypy/rpython/rarithmetic.py Tue Aug 9 01:24:23 2005 @@ -378,3 +378,6 @@ return float("%s%s.%se%s" % (sign, beforept, afterpt, exponent)) # float -> string + +def formatd(fmt, x): + return fmt % (x,) Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Aug 9 01:24:23 2005 @@ -32,6 +32,8 @@ ll_math.ll_math_hypot: 'LL_math_hypot', ll_strtod.ll_strtod_parts_to_float: 'LL_strtod_parts_to_float', + ll_strtod.ll_strtod_formatd: + 'LL_strtod_formatd', } #______________________________________________________ Modified: pypy/dist/pypy/translator/c/src/ll_strtod.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_strtod.h (original) +++ pypy/dist/pypy/translator/c/src/ll_strtod.h Tue Aug 9 01:24:23 2005 @@ -1,4 +1,5 @@ #include +#include double LL_strtod_parts_to_float( RPyString *sign, @@ -54,3 +55,51 @@ } return x; } + + +RPyString *LL_strtod_formatd(RPyString *fmt, double x) { + char buffer[120]; /* this should be enough, from PyString_Format code */ + int buflen = 120; + int res; + res = snprintf(buffer, buflen, RPyString_AsString(fmt), x); + if (res <= 0 || res >= buflen) { + strcpy(buffer, "??.?"); /* should not occur */ + } else { + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + char *p; + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + p = buffer; + + if (*p == '+' || *p == '-') + p++; + + while (isdigit((unsigned char)*p)) + p++; + + if (strncmp(p, decimal_point, decimal_point_len) == 0) + { + *p = '.'; + p++; + if (decimal_point_len > 1) { + int rest_len; + rest_len = strlen(p + (decimal_point_len - 1)); + memmove(p, p + (decimal_point_len - 1), + rest_len); + p[rest_len] = 0; + } + } + } + + } + + return RPyString_FromString(buffer); +} Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Tue Aug 9 01:24:23 2005 @@ -234,3 +234,14 @@ for parts, val in data: assert f(*parts) == val + +def test_rarith_formatd(): + from pypy.rpython.rarithmetic import formatd + def fn(x): + return formatd("%.2f", x) + + f = compile(fn, [float]) + + assert f(0.0) == "0.00" + assert f(1.5) == "1.50" + assert f(2.0) == "2.00" From ericvrp at codespeak.net Tue Aug 9 09:58:50 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 9 Aug 2005 09:58:50 +0200 (CEST) Subject: [pypy-svn] r15798 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050809075850.D5A4927B4D@code1.codespeak.net> Author: ericvrp Date: Tue Aug 9 09:58:48 2005 New Revision: 15798 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/opwriter.py Log: - refactored casts - storing missing functions and operation error message in .ll file - XXX there is still an issue with the pyrex wrapper code. It does not know how to handle a list of rpy_strings. - after translating entire PyPy (86Mb .ll file) these were the messages: ;; XXX: Error: _generic_pow: Variable has no value ;; XXX: Error: exception raising operation invoke:float_add not found ;; XXX: Error: exception raising operation invoke:float_mul not found ;; XXX: Error: exception raising operation invoke:float_pow not found ;; XXX: Error: exception raising operation invoke:float_sub not found ;; XXX: Error: exception raising operation invoke:float_truediv not found ;; XXX: Error: exception raising operation invoke:int_add not found ;; XXX: Error: exception raising operation invoke:int_add_ovf not found ;; XXX: Error: exception raising operation invoke:int_floordiv_ovf_zer not found ;; XXX: Error: exception raising operation invoke:int_lshift_ovf_val not found ;; XXX: Error: exception raising operation invoke:int_mod_ovf_zer not found ;; XXX: Error: exception raising operation invoke:int_mul_ovf not found ;; XXX: Error: exception raising operation invoke:int_neg_ovf not found ;; XXX: Error: exception raising operation invoke:int_sub not found ;; XXX: Error: exception raising operation invoke:int_sub_ovf not found ;; XXX: Error: operation float_abs not found ;; XXX: Error: operation int_abs not found ;; XXX: Error: primitive function %float_add has no implementation ;; XXX: Error: primitive function %float_mul has no implementation ;; XXX: Error: primitive function %float_pow has no implementation ;; XXX: Error: primitive function %float_sub has no implementation ;; XXX: Error: primitive function %float_truediv has no implementation ;; XXX: Error: primitive function %int_add has no implementation ;; XXX: Error: primitive function %int_add_ovf has no implementation ;; XXX: Error: primitive function %int_floordiv_ovf_zer has no implementation ;; XXX: Error: primitive function %int_lshift_ovf_val has no implementation ;; XXX: Error: primitive function %int_mod_ovf_zer has no implementation ;; XXX: Error: primitive function %int_mul_ovf has no implementation ;; XXX: Error: primitive function %int_sub has no implementation ;; XXX: Error: primitive function %int_sub_ovf has no implementation ;; XXX: Error: primitive function %ll_math_frexp has no implementation ;; XXX: Error: primitive function %ll_math_hypot has no implementation ;; XXX: Error: primitive function %ll_math_ldexp has no implementation ;; XXX: Error: primitive function %ll_math_modf has no implementation ;; XXX: Error: primitive function %ll_os_ftruncate has no implementation ;; XXX: Error: primitive function %ll_os_lseek has no implementation ;; XXX: Error: primitive function %ll_os_stat has no implementation Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Tue Aug 9 09:58:48 2005 @@ -15,7 +15,8 @@ self.n_lines += 1 if self.show_line_numbers: line = "%-75s; %d" % (line, self.n_lines) - print >> self.f, line + #print >> self.f, line + self.f.write(line + '\n') def comment(self, line, indent=True): line = ";; " + line Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Tue Aug 9 09:58:48 2005 @@ -18,6 +18,8 @@ from pypy.translator.translator import Translator +import time + function_count = {} class GenLLVM(object): @@ -37,6 +39,7 @@ self.debug = debug def gen_llvm_source(self, func=None): + print 'gen_llvm_source begin) ' + time.ctime() if func is None: func = self.translator.entrypoint self.entrypoint = func @@ -54,7 +57,12 @@ self.db.prepare_repr_arg(c) assert c in self.db.obj2node + print 'gen_llvm_source db.setup_all) ' + time.ctime() + #7 minutes self.db.setup_all() + print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() + print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) + #3 seconds if self.debug: log.gen_llvm_source(self.db.dump_pbcs()) @@ -77,26 +85,34 @@ for typ_decl in self.db.getnodes(): typ_decl.writedatatypedecl(codewriter) + print 'gen_llvm_source typ_decl.writeglobalconstants) ' + time.ctime() + #20 minutes nl(); comment("Global Data") ; nl() for typ_decl in self.db.getnodes(): typ_decl.writeglobalconstants(codewriter) + print 'gen_llvm_source typ_decl.writecomments) ' + time.ctime() + #0 minutes if self.debug: nl(); comment("Comments") ; nl() for typ_decl in self.db.getnodes(): typ_decl.writecomments(codewriter) + print 'gen_llvm_source extdeclarations) ' + time.ctime() nl(); comment("Function Prototypes") ; nl() if self.embedexterns: for extdecl in extdeclarations.split('\n'): codewriter.append(extdecl) + print 'gen_llvm_source self._debug_prototype) ' + time.ctime() if self.debug: self._debug_prototype(codewriter) + print 'gen_llvm_source typ_decl.writedecl) ' + time.ctime() for typ_decl in self.db.getnodes(): typ_decl.writedecl(codewriter) + print 'gen_llvm_source boehm_gc) ' + time.ctime() nl(); comment("Function Implementation") codewriter.startimpl() if use_boehm_gc: @@ -106,9 +122,12 @@ for gc_func in gc_funcs.split('\n'): codewriter.append(gc_func) + print 'gen_llvm_source typ_decl.writeimpl) ' + time.ctime() + #XXX ? minutes for typ_decl in self.db.getnodes(): typ_decl.writeimpl(codewriter) + print 'gen_llvm_source used_external_functions) ' + time.ctime() depdone = {} for funcname,value in ExternalFuncNode.used_external_functions.iteritems(): deps = dependencies(funcname,[]) @@ -118,11 +137,15 @@ try: llvm_code = extfunctions[dep][1] except KeyError: - raise Exception('primitive function %s has no implementation' %(dep,)) + msg = 'primitive function %s has no implementation' % dep + codewriter.comment('XXX: Error: ' + msg) + #raise Exception('primitive function %s has no implementation' %(dep,)) + continue for extfunc in llvm_code.split('\n'): codewriter.append(extfunc) depdone[dep] = True + print 'gen_llvm_source entrypoint) ' + time.ctime() #XXX use codewriter methods here decl = self.entrynode.getdecl() t = decl.split('%', 1) @@ -152,6 +175,7 @@ codewriter.newline() comment("End of file") ; nl() + print 'gen_llvm_source return) ' + time.ctime() return filename def create_module(self, filename, exe_name=None): Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Tue Aug 9 09:58:48 2005 @@ -76,7 +76,7 @@ br bool %tmp.12, label %then.1, label %return then.1: ; preds = %entry - call void %RaiseSimpleException( int 1, sbyte* getelementptr ([16 x sbyte]* %.str_1, int 0, int 0) ) + ; XXX disabled for now: call void %RaiseSimpleException( int 1, sbyte* getelementptr ([16 x sbyte]* %.str_1, int 0, int 0) ) ret void return: ; preds = %entry Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Tue Aug 9 09:58:48 2005 @@ -1,4 +1,8 @@ -extdeclarations = "" +extdeclarations = """ +declare ccc double %pow(double, double) +declare ccc double %fmod(double, double) +""" + extfunctions = {} @@ -107,6 +111,45 @@ #XXX TODO +#extfunctions["%float_pow"] = ((), """ +#fastcc double %float_pow(double %x, double %y) { +# ; XXX ERROR float_pow exception raising not implemented +# %r = call ccc double %pow(double %x, double %y) +# ret double %r +#} +# +#""") +# +#extfunctions["%float_mod"] = ((), """ +#fastcc double %float_mod(double %x, double %y) { +# ; XXX ERROR float_mod exception raising not implemented +# %r = call ccc double %fmod(double %x, double %y) +# ret double %r +#} +# +#""") +# +#for func in 'float_abs float_sub float_add float_mul float_div'.split(): +# extfunctions["%" + func] = ((), """ +#fastcc double %%%(func)s(double %%x, double %%y) { +# ; XXX ERROR %(func)s exception raising not implemented +# ret double 0.0 +#} +# +#""" % locals()) +# +#for func in 'int_abs int_sub int_add int_mul int_div int_mod int_add_ovf int_sub_ovf int_mul_ovf int_floordiv_ovf int_mod_ovf int_floordiv_ovf_zer int_mod_ovf_zer int_lshift_ovf int_lshift_ovf_val int_rshift_val int_lshift_val'.split(): +# extfunctions["%" + func] = ((), """ +#fastcc int %%%(func)s(int %%x, int %%y) { +# ; XXX ERROR %(func)s exception raising not implemented +# ret int 0 +#} +# +#""" % locals()) + + +#XXX TODO + #overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) ok else _OVF() #binary with overflow Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Tue Aug 9 09:58:48 2005 @@ -89,16 +89,27 @@ self.binaryop(op) elif op.opname in self.shift_operations: self.shiftop(op) + elif op.opname.startswith('cast_'): + self.cast_primitive(op) else: meth = getattr(self, op.opname, None) - assert meth is not None, "operation %s not found" %(op.opname,) + if not meth: + msg = "operation %s not found" %(op.opname,) + self.codewriter.comment('XXX: Error: ' + msg) + #assert meth is not None, msg + return meth(op) def _generic_pow(self, op, onestr): mult_type = self.db.repr_arg_type(op.args[0]) mult_val = self.db.repr_arg(op.args[0]) last_val = mult_val - operand = int(op.args[1].value) + try: + operand = int(op.args[1].value) + except: + msg = 'XXX: Error: _generic_pow: Variable has no value' + self.codewriter.comment(msg) + return if operand < 1: res_val = onestr else: @@ -130,6 +141,7 @@ ) def int_neg(self, op): self._generic_neg(op, "0") + uint_neg = int_neg #this is really generates, don't know why def float_neg(self, op): self._generic_neg(op, "0.0") @@ -141,12 +153,13 @@ self.db.repr_arg(op.args[0]), "true") - def uint_invert(self, op): + def int_invert(self, op): #XXX do we have a test for this, it doesn't look right? self.codewriter.binaryop("xor", self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), 1) + uint_invert = int_invert def binaryop(self, op): name = self.binary_operations[op.opname] @@ -178,16 +191,16 @@ fromvar = self.db.repr_arg(op.args[0]) fromtype = self.db.repr_arg_type(op.args[0]) self.codewriter.cast(targetvar, fromtype, fromvar, targettype) - - cast_bool_to_char = cast_bool_to_int = cast_bool_to_uint = cast_primitive - cast_char_to_bool = cast_char_to_int = cast_char_to_uint = cast_primitive - cast_int_to_bool = cast_int_to_char = cast_int_to_uint = cast_primitive - cast_uint_to_bool = cast_uint_to_char = cast_uint_to_int = cast_primitive - cast_int_to_float = cast_float_to_int = cast_primitive - cast_unichar_to_int = cast_int_to_unichar = cast_primitive - cast_pointer = cast_primitive same_as = cast_primitive + #cast_bool_to_char = cast_bool_to_int = cast_bool_to_uint = cast_bool_to_float = cast_bool_to_unichar = cast_primitive + #cast_char_to_bool = cast_char_to_int = cast_char_to_uint = cast_char_to_float = cast_char_to_unichar = cast_primitive + #cast_int_to_bool = cast_int_to_char = cast_int_to_uint = cast_int_to_float = cast_int_to_unichar = cast_primitive + #cast_uint_to_bool = cast_uint_to_char = cast_uint_to_int = cast_uint_to_float = cast_uint_to_unichar = cast_primitive + #cast_float_to_bool = cast_float_to_char= cast_float_to_int = cast_float_to_uint = cast_float_to_unichar = cast_primitive + #cast_unichar_to_bool=cast_unichar_to_char=cast_unichar_to_int=cast_unichar_to_uint=cast_unichar_to_float= cast_primitive + #cast_pointer = cast_primitive + def int_is_true(self, op): self.codewriter.binaryop("setne", self.db.repr_arg(op.result), @@ -246,8 +259,9 @@ op_args = ['%' + opname] + op_args functionref = op_args[0] ExternalFuncNode.used_external_functions[functionref] = True - assert functionref in extfunctions, \ - "exception raising operation %(opname)s has no implementation" % locals() + msg = "exception raising operation %s not found" %(op.opname,) + self.codewriter.comment('XXX: Error: ' + msg) + #assert functionref in extfunctions, msg assert len(op_args) >= 1 assert len(self.block.exits) >= 2 #at least one label and one exception label @@ -392,7 +406,7 @@ ("uint", index)) self.codewriter.load(targetvar, targettype, tmpvar) else: - self.codewriter.comment("***Skipping operation getfield()***") + self.codewriter.comment("***Skipping operation getfield()***") #XXX what if this the last operation of the exception block? def getsubstruct(self, op): struct, structtype = self.db.repr_argwithtype(op.args[0]) From ericvrp at codespeak.net Tue Aug 9 10:00:19 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 9 Aug 2005 10:00:19 +0200 (CEST) Subject: [pypy-svn] r15799 - pypy/dist/pypy/translator/goal Message-ID: <20050809080019.11BCE27B51@code1.codespeak.net> Author: ericvrp Date: Tue Aug 9 10:00:18 2005 New Revision: 15799 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: - Added "-llvm" option. Whenever the C backend is called (generating module, generator standalone) this option should call the llvm backend instead. Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Tue Aug 9 10:00:18 2005 @@ -18,6 +18,7 @@ -no-o Don't do backend-oriented optimizations -no-c Don't generate the C code -fork (UNIX) Create a restartable checkpoint after annotation + -llvm Use LLVM instead of C -c Generate the C code, but don't compile it -o Generate and compile the C code, but don't run it -tcc Equivalent to the envvar PYPY_CC='tcc -shared -o "%s.so" "%s.c"' @@ -289,6 +290,7 @@ '-no-c': False, '-c': False, '-o': False, + '-llvm': False, '-no-mark-some-objects': False, '-no-a': False, '-no-t': False, @@ -595,14 +597,23 @@ elif options['-no-c']: print 'Not generating C code.' elif options['-c']: - print 'Generating C code without compiling it...' - filename = t.ccompile(really_compile=False, - standalone=standalone) + if option['-llvm']: + print 'Generating LLVM code without compiling it...' + filename = t.llvmcompile(really_compile=False, + standalone=standalone) + else: + print 'Generating C code without compiling it...' + filename = t.ccompile(really_compile=False, + standalone=standalone) update_usession_dir() print 'Written %s.' % (filename,) else: - print 'Generating and compiling C code...' - c_entry_point = t.ccompile(standalone=standalone) + if options['-llvm']: + print 'Generating and compiling LLVM code...' + c_entry_point = t.llvmcompile(standalone=standalone) + else: + print 'Generating and compiling C code...' + c_entry_point = t.ccompile(standalone=standalone) update_usession_dir() if not options['-o']: print 'Running!' From pedronis at codespeak.net Tue Aug 9 13:50:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 9 Aug 2005 13:50:28 +0200 (CEST) Subject: [pypy-svn] r15808 - in pypy/dist/pypy: lib module/__builtin__ objspace/std translator Message-ID: <20050809115028.15F6327B48@code1.codespeak.net> Author: pedronis Date: Tue Aug 9 13:50:26 2005 New Revision: 15808 Modified: pypy/dist/pypy/lib/_formatting.py pypy/dist/pypy/module/__builtin__/__init__.py pypy/dist/pypy/module/__builtin__/special.py pypy/dist/pypy/objspace/std/strutil.py pypy/dist/pypy/translator/geninterplevel.py Log: do the deed: delegate float->string and string->float to the backend Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Tue Aug 9 13:50:26 2005 @@ -241,24 +241,31 @@ r = self._format(v) return self.numeric_postprocess(r, sign) + def _formatd(self, kind, v): + fmt = '%' + (self.flags.f_alt and '#' or '') + '.' + str(self.prec) + kind + import __builtin__ + return __builtin__._formatd(fmt, v) class FloatFFormatter(FloatFormatter): def _format(self, v): if v/1e25 > 1e25: return FloatGFormatter('g', self.flags, self.width, self.prec, self.value).format() - ds, k = flonum2digits(v) - digits = self.fDigits(ds, k) - if not self.flags.f_alt: - digits = digits.rstrip('.') - return digits + + return self._formatd('f', v) + #ds, k = flonum2digits(v) + #digits = self.fDigits(ds, k) + #if not self.flags.f_alt: + # digits = digits.rstrip('.') + #return digits class FloatEFormatter(FloatFormatter): def _format(self, v): - ds, k = flonum2digits(v) - digits = self.eDigits(ds) - return "%s%c%+03d"%(digits, self.char, k-1) + return self._formatd('e', v) + #ds, k = flonum2digits(v) + #digits = self.eDigits(ds) + #return "%s%c%+03d"%(digits, self.char, k-1) class FloatGFormatter(FloatFormatter): @@ -267,19 +274,20 @@ # Gah, this still isn't quite right in the f_alt case. # (One has to wonder who might care). def _format(self, v): - ds, k = flonum2digits(v) - ds = ds[:self.prec] # XXX rounding! - if -4 < k <= self.prec: - digits = self.fDigits(ds, k) - if not self.flags.f_alt: - digits = digits.rstrip('0').rstrip('.') - r = digits - else: - digits = self.eDigits(ds) - if not self.flags.f_alt: - digits = digits.rstrip('0').rstrip('.') - r = "%se%+03d"%(digits, k-1) - return r + return self._formatd('g', v) + #ds, k = flonum2digits(v) + #ds = ds[:self.prec] # XXX rounding! + #if -4 < k <= self.prec: + # digits = self.fDigits(ds, k) + # if not self.flags.f_alt: + # digits = digits.rstrip('0').rstrip('.') + # r = digits + #else: + # digits = self.eDigits(ds) + # if not self.flags.f_alt: + # digits = digits.rstrip('0').rstrip('.') + # r = "%se%+03d"%(digits, k-1) + #return r class HexFormatter(Formatter): Modified: pypy/dist/pypy/module/__builtin__/__init__.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/__init__.py (original) +++ pypy/dist/pypy/module/__builtin__/__init__.py Tue Aug 9 13:50:26 2005 @@ -107,6 +107,9 @@ 'eval' : 'compiling.eval', '__import__' : 'importing.importhook', + + # float->string helper + '_formatd' : 'special._formatd' } def pick_builtin(self, w_globals): Modified: pypy/dist/pypy/module/__builtin__/special.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/special.py (original) +++ pypy/dist/pypy/module/__builtin__/special.py Tue Aug 9 13:50:26 2005 @@ -1,4 +1,11 @@ +from pypy.interpreter import gateway +from pypy.rpython import rarithmetic def _isfake(space, w_obj): return space.wrap(bool(w_obj.typedef.fakedcpytype)) #return space.wrap(bool(getattr(w_obj.typedef, 'fakedcpytype', None))) + + +def _formatd(space, fmt, x): + return space.wrap(rarithmetic.formatd(fmt, x)) +_formatd.unwrap_spec = [gateway.ObjSpace, str, float] Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Tue Aug 9 13:50:26 2005 @@ -2,7 +2,7 @@ Pure Python implementation of string utilities. """ -from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_float_to_int +from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_float_to_int, parts_to_float # XXX factor more functions out of stringobject.py. # This module is independent from PyPy. @@ -376,3 +376,28 @@ r = -r return r + +disabled_string_to_float = string_to_float # not accurate enough + +def string_to_float(s): + """ + Conversion of string to float. + This version tries to only raise on invalid literals. + Overflows should be converted to infinity whenever possible. + """ + + s = strip_spaces(s) + + if not s: + raise ParseStringError("empty string for float()") + + # 1) parse the string into pieces. + sign, before_point, after_point, exponent = break_up_float(s) + + if not before_point and not after_point: + raise ParseStringError("invalid string literal for float()") + + try: + return parts_to_float(sign, before_point, after_point, exponent) + except ValueError: + raise ParseStringError("invalid string literal for float()") Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Tue Aug 9 13:50:26 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.8' # bump this for substantial changes +GI_VERSION = '1.1.9' # bump this for substantial changes # ____________________________________________________________ try: From cfbolz at codespeak.net Tue Aug 9 13:56:43 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 13:56:43 +0200 (CEST) Subject: [pypy-svn] r15809 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050809115643.C726427B48@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 13:56:43 2005 New Revision: 15809 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: fixed conversion of structs that are really substructures of larger structs. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Tue Aug 9 13:56:43 2005 @@ -15,28 +15,28 @@ self.converted = {} self.curraddress = address - def convert(self, val_or_ptr, inline_to_addr=None): + def convert(self, val_or_ptr, inline_to_addr=None, from_parent=False): TYPE = lltype.typeOf(val_or_ptr) if isinstance(TYPE, lltype.Primitive): if inline_to_addr is not None: inline_to_addr._store(primitive_to_fmt[TYPE], val_or_ptr) return val_or_ptr elif isinstance(TYPE, lltype.Array): - return self.convert_array(val_or_ptr, inline_to_addr) + return self.convert_array(val_or_ptr, inline_to_addr, from_parent) elif isinstance(TYPE, lltype.Struct): - return self.convert_struct(val_or_ptr, inline_to_addr) + return self.convert_struct(val_or_ptr, inline_to_addr, from_parent) elif isinstance(TYPE, lltype.Ptr): - return self.convert_pointer(val_or_ptr, inline_to_addr) + return self.convert_pointer(val_or_ptr, inline_to_addr, from_parent) elif isinstance(TYPE, lltype.OpaqueType): - return self.convert_object(val_or_ptr, inline_to_addr) + return self.convert_object(val_or_ptr, inline_to_addr, from_parent) elif isinstance(TYPE, lltype.FuncType): - return self.convert_object(val_or_ptr, inline_to_addr) + return self.convert_object(val_or_ptr, inline_to_addr, from_parent) elif isinstance(TYPE, lltype.PyObjectType): - return self.convert_object(val_or_ptr, inline_to_addr) + return self.convert_object(val_or_ptr, inline_to_addr, from_parent) else: assert 0, "don't know about %s" % (val_or_ptr, ) - def convert_array(self, _array, inline_to_addr): + def convert_array(self, _array, inline_to_addr, from_parent): if _array in self.converted: address = self.converted[_array] assert inline_to_addr is None or address == inline_to_addr @@ -54,15 +54,20 @@ varsize = get_variable_size(TYPE) self.curraddress += size for item in _array.items: - self.convert(item, curraddr) + self.convert(item, curraddr, from_parent=True) curraddr += varsize return startaddr - def convert_struct(self, _struct, inline_to_addr): + def convert_struct(self, _struct, inline_to_addr, from_parent): if _struct in self.converted: address = self.converted[_struct] assert inline_to_addr is None or address == inline_to_addr return address + parent = _struct._parentstructure() + if parent is not None and not from_parent: + address = self.convert(parent) + layout = get_layout(lltype.typeOf(parent)) + return address + layout[_struct._parent_index] TYPE = lltype.typeOf(_struct) layout = get_layout(TYPE) if TYPE._arrayfld is not None: @@ -78,10 +83,10 @@ self.curraddress += size for name in TYPE._flds: addr = startaddr + layout[name] - self.convert(getattr(_struct, name), addr) + self.convert(getattr(_struct, name), addr, from_parent=True) return startaddr - def convert_pointer(self, _ptr, inline_to_addr): + def convert_pointer(self, _ptr, inline_to_addr, from_parent): TYPE = lltype.typeOf(_ptr) if _ptr._obj is not None: addr = self.convert(_ptr._obj) @@ -92,7 +97,7 @@ inline_to_addr.address[0] = addr return simulatorptr(TYPE, addr) - def convert_object(self, _obj, inline_to_addr): + def convert_object(self, _obj, inline_to_addr, from_parent): if inline_to_addr is not None: inline_to_addr.attached[0] = _obj return inline_to_addr Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Tue Aug 9 13:56:43 2005 @@ -118,7 +118,7 @@ fpter = cvter.convert(llfuncptr) assert fpter(1, 2) == 3 -def DONOTtest_convertsubstructure(): +def test_convertsubstructure(): cvter = LLTypeConverter(lladdress.raw_malloc(100)) S1 = lltype.GcStruct("s1", ("v1", lltype.Signed)) S2 = lltype.GcStruct("s2", ("s", S1), ("v2", lltype.Signed)) From adim at codespeak.net Tue Aug 9 14:27:10 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Tue, 9 Aug 2005 14:27:10 +0200 (CEST) Subject: [pypy-svn] r15811 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050809122710.AEF9F27B48@code1.codespeak.net> Author: adim Date: Tue Aug 9 14:27:07 2005 New Revision: 15811 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: implemented for stmts (+break and pass) Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Tue Aug 9 14:27:07 2005 @@ -482,6 +482,36 @@ break # break is not necessary builder.push(ast.If(tests, else_)) +def build_pass_stmt(builder, nb): + """past_stmt: 'pass'""" + L = get_atoms(builder, nb) + assert len(L) == 1 + builder.push(ast.Pass()) + + +def build_break_stmt(builder, nb): + """past_stmt: 'pass'""" + L = get_atoms(builder, nb) + assert len(L) == 1 + builder.push(ast.Break()) + + +def build_for_stmt(builder, nb): + """for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]""" + L = get_atoms(builder, nb) + else_ = None + # skip 'for' + assign = to_lvalue(L[1], consts.OP_ASSIGN) + # skip 'in' + iterable = L[3] + # skip ':' + body = L[5] + # if there is a "else" statement + if len(L) > 6: + # skip 'else' and ':' + else_ = L[8] + builder.push(ast.For(assign, iterable, body, else_)) + def parse_argument(tokens): """parses function call arguments""" @@ -660,6 +690,9 @@ sym.return_stmt : build_return_stmt, sym.suite : build_suite, sym.if_stmt : build_if_stmt, + sym.pass_stmt : build_pass_stmt, + sym.break_stmt : build_break_stmt, + sym.for_stmt : build_for_stmt, # sym.parameters : build_parameters, } Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py Tue Aug 9 14:27:07 2005 @@ -1,3 +1,11 @@ for x in range(10): pass +for x in range(5): + a += x + b += 2 + if False: + break +else: + c = 3 + Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Tue Aug 9 14:27:07 2005 @@ -182,6 +182,7 @@ 'snippet_1.py', 'snippet_several_statements.py', 'snippet_simple_function.py', + 'snippet_simple_for_loop.py', # 'snippet_2.py', # 'snippet_3.py', # 'snippet_4.py', @@ -200,7 +201,6 @@ # 'snippet_samples.py', # 'snippet_simple_assignment.py', # 'snippet_simple_class.py', -# 'snippet_simple_for_loop.py', # 'snippet_simple_in_expr.py', # 'snippet_slice.py', # 'snippet_whitespaces.py', From cfbolz at codespeak.net Tue Aug 9 14:32:30 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 14:32:30 +0200 (CEST) Subject: [pypy-svn] r15813 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050809123230.B5B5827B48@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 14:32:29 2005 New Revision: 15813 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: oops, all the test_llinterpsim tests (always run all tests :-( ) failed because I didn't adapt the size calculation. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Tue Aug 9 14:32:29 2005 @@ -160,6 +160,9 @@ candidates.append(item) elif isinstance(cand, lltype._struct): seen[cand] = True + parent = cand._parentstructure() + if parent is not None: + candidates.append(parent) TYPE = cand._TYPE if TYPE._arrayfld is not None: total_size += get_total_size( Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Tue Aug 9 14:32:29 2005 @@ -127,3 +127,10 @@ s1 = cvter.convert(lls1) s2 = cast_pointer(lltype.Ptr(S2), s1) assert s2.v2 == 0 + +def test_convertsubstructure_of_array(): + cvter = LLTypeConverter(lladdress.raw_malloc(100)) + S1 = lltype.Struct("s1", ("v1", lltype.Signed)) + A = lltype.GcArray(S1) + lla = lltype.malloc(A, 3) + s1 = cvter.convert(lla[0]) From ale at codespeak.net Tue Aug 9 16:12:46 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 9 Aug 2005 16:12:46 +0200 (CEST) Subject: [pypy-svn] r15815 - pypy/dist/pypy/module/__builtin__ Message-ID: <20050809141246.E47A027B48@code1.codespeak.net> Author: ale Date: Tue Aug 9 16:12:46 2005 New Revision: 15815 Modified: pypy/dist/pypy/module/__builtin__/operation.py Log: Trying to get reversed in sync with CPython. It checks for __reversed__, then checks for __len__ and __getitem__. Unfortunately this is not enough for disallowing dicts Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Tue Aug 9 16:12:46 2005 @@ -18,8 +18,13 @@ return space.call_function(func,w_iterable) # else return W_IterObject with reverse set else: - w_seq = W_SeqIterObject(space,w_iterable,-1,True) - return w_seq + + getitem = space.lookup(w_iterable,'__getitem__') + len = space.lookup(w_iterable,'__len__') + if getitem and len : + w_seq = W_SeqIterObject(space,w_iterable,-1,True) + return w_seq + raise OperationError(space.wrap(TypeError),space.wrap('argument to reversed() must be a sequence')) def abs(space, w_val): "abs(number) -> number\n\nReturn the absolute value of the argument." From ale at codespeak.net Tue Aug 9 16:16:56 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 9 Aug 2005 16:16:56 +0200 (CEST) Subject: [pypy-svn] r15816 - pypy/dist/pypy/objspace/std Message-ID: <20050809141656.CC0BE27B48@code1.codespeak.net> Author: ale Date: Tue Aug 9 16:16:56 2005 New Revision: 15816 Modified: pypy/dist/pypy/objspace/std/dicttype.py Log: Adding __reversed__ for dicts. It raises a TypeError. Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Tue Aug 9 16:16:56 2005 @@ -1,5 +1,6 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all +from pypy.interpreter.error import OperationError dict_copy = MultiMethod('copy', 1) dict_items = MultiMethod('items', 1) @@ -15,6 +16,10 @@ dict_iteritems = MultiMethod('iteritems', 1) dict_iterkeys = MultiMethod('iterkeys', 1) dict_itervalues = MultiMethod('itervalues', 1) +dict_reversed = MultiMethod('__reversed__', 1) + +def dict_reversed__ANY(space, w_dict): + raise OperationError(space.wrap(TypeError),space.wrap('argument to reversed() must be a sequence')) #dict_fromkeys = MultiMethod('fromkeys', 2, varargs=True) # This can return when multimethods have been fixed #dict_str = StdObjSpace.str From arigo at codespeak.net Tue Aug 9 16:19:16 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 16:19:16 +0200 (CEST) Subject: [pypy-svn] r15817 - in pypy/dist/pypy: annotation translator translator/goal Message-ID: <20050809141916.C5ABB27B48@code1.codespeak.net> Author: arigo Date: Tue Aug 9 16:19:12 2005 New Revision: 15817 Modified: pypy/dist/pypy/annotation/policy.py pypy/dist/pypy/translator/annrpython.py pypy/dist/pypy/translator/goal/translate_pypy.py Log: Complain the first time a SomeObject is seen for stand-alone translation targets. Useful for targetpypystandalone. To do later: allow a target to return a custom policy. Modified: pypy/dist/pypy/annotation/policy.py ============================================================================== --- pypy/dist/pypy/annotation/policy.py (original) +++ pypy/dist/pypy/annotation/policy.py Tue Aug 9 16:19:12 2005 @@ -8,6 +8,7 @@ class BasicAnnotatorPolicy: + allow_someobjects = True def specialize(pol, bookkeeper, spaceop, func, args, mono): return None, None Modified: pypy/dist/pypy/translator/annrpython.py ============================================================================== --- pypy/dist/pypy/translator/annrpython.py (original) +++ pypy/dist/pypy/translator/annrpython.py Tue Aug 9 16:19:12 2005 @@ -227,6 +227,25 @@ history.append(self.bindings[arg]) cause_history = self.binding_cause_history.setdefault(arg, []) cause_history.append(self.binding_caused_by[arg]) + degenerated = (s_value.__class__ is annmodel.SomeObject and + s_value.knowntype is not type) + if degenerated and not self.policy.allow_someobjects: + msglines = ["annotation of %r degenerated to SomeObject()" % (arg,)] + try: + position_key = self.bookkeeper.position_key + except AttributeError: + pass + else: + msglines.append(".. %r position: %s" % ( + arg, self.whereami(position_key),)) + if called_from is not None: + msglines.append(".. called from %r" % (called_from,)) + if hasattr(called_from, '__module__'): + msglines[-1] += " from module %r"% (called_from.__module__,) + if s_value.origin is not None: + msglines.append(".. SomeObject() origin: %s" % ( + self.whereami(s_value.origin),)) + raise AnnotatorError('\n'.join(msglines)) self.bindings[arg] = s_value if annmodel.DEBUG: if arg in self.return_bindings: @@ -234,7 +253,7 @@ (self.whereami((self.return_bindings[arg], None, None)), s_value)) - if arg in self.return_bindings and s_value == annmodel.SomeObject(): + if arg in self.return_bindings and degenerated: log.red("*** WARNING: %s result degenerated to SomeObject" % self.whereami((self.return_bindings[arg],None, None))) Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Tue Aug 9 16:19:12 2005 @@ -106,15 +106,17 @@ a = t.annotator t.frozen = False standalone = inputtypes is None + policy = PyPyAnnotatorPolicy() if standalone: ldef = listdef.ListDef(None, annmodel.SomeString()) inputtypes = [annmodel.SomeList(ldef)] + policy.allow_someobjects = False if listen_port: run_async_server() if not options['-no-a']: print 'Annotating...' - a = t.annotate(inputtypes, policy=PyPyAnnotatorPolicy()) + a = t.annotate(inputtypes, policy=policy) sanity_check_exceptblocks(t) lost = query.sanity_check_methods(t) assert not lost, "lost methods, something gone wrong with the annotation of method defs" From cfbolz at codespeak.net Tue Aug 9 16:26:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 16:26:17 +0200 (CEST) Subject: [pypy-svn] r15819 - pypy/dist/pypy/rpython/memory Message-ID: <20050809142617.AB6AA27B48@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 16:26:17 2005 New Revision: 15819 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: made structs of void work. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Tue Aug 9 16:26:17 2005 @@ -18,7 +18,7 @@ def convert(self, val_or_ptr, inline_to_addr=None, from_parent=False): TYPE = lltype.typeOf(val_or_ptr) if isinstance(TYPE, lltype.Primitive): - if inline_to_addr is not None: + if inline_to_addr is not None and TYPE != lltype.Void: inline_to_addr._store(primitive_to_fmt[TYPE], val_or_ptr) return val_or_ptr elif isinstance(TYPE, lltype.Array): Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Tue Aug 9 16:26:17 2005 @@ -40,6 +40,8 @@ def get_fixed_size(TYPE): if isinstance(TYPE, lltype.Primitive): + if TYPE == lltype.Void: + return 0 return struct.calcsize(primitive_to_fmt[TYPE]) elif isinstance(TYPE, lltype.Ptr): return struct.calcsize("P") @@ -130,6 +132,8 @@ T = self._T._flds[field_name] base = self._layout[field_name] if isinstance(T, lltype.Primitive): + if T == lltype.Void: + return None res = (self._address + offset)._load(primitive_to_fmt[T])[0] if T == lltype.Bool: res = bool(res) @@ -151,6 +155,8 @@ T = self._T._flds[field_name] offset = self._layout[field_name] if isinstance(T, lltype.Primitive): + if T == lltype.Void: + return (self._address + offset)._store(primitive_to_fmt[T], value) return elif isinstance(T, lltype.Ptr): From arigo at codespeak.net Tue Aug 9 16:32:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 16:32:29 +0200 (CEST) Subject: [pypy-svn] r15821 - in pypy/dist/pypy: annotation rpython rpython/test Message-ID: <20050809143229.62E0027B48@code1.codespeak.net> Author: arigo Date: Tue Aug 9 16:32:17 2005 New Revision: 15821 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/rpython/annlowlevel.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rconstantdict.py pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/robject.py pypy/dist/pypy/rpython/rpbc.py pypy/dist/pypy/rpython/rptr.py pypy/dist/pypy/rpython/rrange.py pypy/dist/pypy/rpython/rspecialcase.py pypy/dist/pypy/rpython/rstr.py pypy/dist/pypy/rpython/rtuple.py pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/rpython/test/test_rpbc.py Log: issue105 testing Require explicit care about exception catching in the RTyper. This is done with an extension of the interface of 'hop' -- which is already quite complicated :-( * hop.has_implicit_exception(cls) checks if the current high-level op is in the scope of a branch catching 'cls', as previously, but now also records that the rtyper cares about this case. * hop.exception_is_here() is called with no argument just before a llop is generated. It means that the llop in question will be the one that should be protected by the exception catching. If has_implicit_exception() was called before, then exception_is_here() verifies that *all* except links in the graph have indeed been checked for with an has_implicit_exception(). This is not verified if has_implicit_exception() has never been called -- useful for 'direct_call' and other operations that can just raise any exception. * hop.exception_cannot_occur() is a special case for override:ignore meaning that there is, after all, no operation left that could raise an exception. (The RTyper class normally verifies that exception_is_here() was really called once for each high-level operation that is in the scope of exception-catching links.) This required adding the correct has_implicit_exception() and exception_is_here() calls all over the place in the r*.py files. It's possible that I have overlooked 1-2 untested places. Indeed, I found a couple of typos looking around. It also required more precise 'can_only_throw' attributes in annotation/binary.py, which is good (but again easy to overlook 1-2 places). Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Tue Aug 9 16:32:17 2005 @@ -379,15 +379,18 @@ def getitem((dic1, obj2)): getbookkeeper().count("dict_getitem", dic1) return dic1.dictdef.read_value() + getitem.can_only_throw = [KeyError] def setitem((dic1, obj2), s_value): getbookkeeper().count("dict_setitem", dic1) dic1.dictdef.generalize_key(obj2) dic1.dictdef.generalize_value(s_value) + setitem.can_only_throw = [KeyError] def delitem((dic1, obj1)): getbookkeeper().count("dict_delitem", dic1) pass + delitem.can_only_throw = [KeyError] class __extend__(pairtype(SomeSlice, SomeSlice)): @@ -409,6 +412,7 @@ else: getbookkeeper().count("tuple_random_getitem", tup1) return unionof(*tup1.items) + getitem.can_only_throw = [IndexError] class __extend__(pairtype(SomeList, SomeInteger)): @@ -420,40 +424,48 @@ def getitem((lst1, int2)): getbookkeeper().count("list_getitem", int2) return lst1.listdef.read_item() + getitem.can_only_throw = [IndexError] def setitem((lst1, int2), s_value): getbookkeeper().count("list_setitem", int2) lst1.listdef.mutate() lst1.listdef.generalize(s_value) + setitem.can_only_throw = [IndexError] def delitem((lst1, int2)): getbookkeeper().count("list_delitem", int2) lst1.listdef.resize() + delitem.can_only_throw = [IndexError] class __extend__(pairtype(SomeList, SomeSlice)): def getitem((lst, slic)): #return getbookkeeper().newlist(lst.listdef.read_item()) return SomeList(lst.listdef) + getitem.can_only_throw = [] def setitem((lst, slic), s_iterable): # we need the same unifying effect as the extend() method for # the case lst1[x:y] = lst2. lst.method_extend(s_iterable) + setitem.can_only_throw = [] def delitem((lst1, slic)): lst1.listdef.resize() + delitem.can_only_throw = [] class __extend__(pairtype(SomeString, SomeSlice)): def getitem((str1, slic)): return SomeString() + getitem.can_only_throw = [] class __extend__(pairtype(SomeString, SomeInteger)): def getitem((str1, int2)): getbookkeeper().count("str_getitem", int2) return SomeChar() + getitem.can_only_throw = [IndexError] def mul((str1, int2)): # xxx do we want to support this getbookkeeper().count("str_mul", str1, int2) @@ -591,19 +603,21 @@ def getitem((p, int1)): v = p.ll_ptrtype._example()[0] return ll_to_annotation(v) + getitem.can_only_throw = [] def setitem((p, int1), s_value): v_lltype = annotation_to_lltype(s_value) p.ll_ptrtype._example()[0] = v_lltype._defl() + setitem.can_only_throw = [] class __extend__(pairtype(SomePtr, SomeObject)): def union((p, obj)): assert False, ("mixing pointer type %r with something else %r" % (p.ll_ptrtype, obj)) - def gettitem((p, obj)): + def getitem((p, obj)): assert False,"ptr %r getitem index not an int: %r" % (p.ll_ptrtype, obj) - def settitem((p, obj)): + def setitem((p, obj)): assert False,"ptr %r setitem index not an int: %r" % (p.ll_ptrtype, obj) class __extend__(pairtype(SomeObject, SomePtr)): @@ -635,10 +649,12 @@ def getitem((s_taa, s_int)): from pypy.annotation.model import lltype_or_address_to_annotation return lltype_or_address_to_annotation(s_taa.type) + getitem.can_only_throw = [] def setitem((s_taa, s_int), s_value): from pypy.annotation.model import annotation_to_lltype_or_address assert annotation_to_lltype_or_address(s_value) is s_taa.type + setitem.can_only_throw = [] class __extend__(pairtype(SomeAddress, SomeInteger)): Modified: pypy/dist/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/dist/pypy/rpython/annlowlevel.py (original) +++ pypy/dist/pypy/rpython/annlowlevel.py Tue Aug 9 16:32:17 2005 @@ -30,6 +30,7 @@ return getattr(self.val, '__name__', repr(self.val)) + 'Const' class LowLevelAnnotatorPolicy(BasicAnnotatorPolicy): + allow_someobjects = False def specialize(pol, bookkeeper, spaceop, func, args, mono): args_s, kwds_s = args.unpack() Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Tue Aug 9 16:32:17 2005 @@ -277,11 +277,13 @@ if extfuncinfo.ll_annotable: def rtype_extfunc(hop): vars = hop.inputargs(*hop.args_r) + hop.exception_is_here() return hop.gendirectcall(ll_function, *vars) else: def rtype_extfunc(hop): resulttype = hop.r_result vars = hop.inputargs(*hop.args_r) + hop.exception_is_here() return hop.llops.genexternalcall(ll_function.__name__, vars, resulttype=resulttype, _callable = ll_function) Modified: pypy/dist/pypy/rpython/rconstantdict.py ============================================================================== --- pypy/dist/pypy/rpython/rconstantdict.py (original) +++ pypy/dist/pypy/rpython/rconstantdict.py Tue Aug 9 16:32:17 2005 @@ -99,6 +99,8 @@ v_dict, v_key = hop.inputargs(r_dict, r_dict.key_repr) hashcompute = r_dict.get_key_hash_function() chashcompute = hop.inputconst(lltype.Void, hashcompute) + hop.has_implicit_exception(KeyError) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_constantdict_getitem, v_dict, v_key, chashcompute) Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Tue Aug 9 16:32:17 2005 @@ -141,10 +141,14 @@ def rtype_getitem((r_dict, r_string), hop): v_dict, v_key = hop.inputargs(r_dict, rstr.string_repr) + hop.has_implicit_exception(KeyError) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_strdict_getitem, v_dict, v_key) def rtype_delitem((r_dict, r_string), hop): v_dict, v_key = hop.inputargs(r_dict, rstr.string_repr) + hop.has_implicit_exception(KeyError) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_strdict_delitem, v_dict, v_key) def rtype_setitem((r_dict, r_string), hop): @@ -320,6 +324,8 @@ def rtype_next(self, hop): v_iter, = hop.inputargs(self) + hop.has_implicit_exception(StopIteration) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_strdictnext, v_iter) def ll_strdictiter(ITERPTR, d): Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Tue Aug 9 16:32:17 2005 @@ -117,17 +117,20 @@ vlist = hop.inputargs(Unsigned, Unsigned, Void)[:2] else: vlist = hop.inputargs(Unsigned, Unsigned, Unsigned) + hop.exception_is_here() return hop.genop('uint_pow' + suffix, vlist, resulttype=Unsigned) else: if s_int3.is_constant() and s_int3.const is None: vlist = hop.inputargs(Signed, Signed, Void)[:2] else: vlist = hop.inputargs(Signed, Signed, Signed) + hop.exception_is_here() return hop.genop('int_pow' + suffix, vlist, resulttype=Signed) def rtype_pow_ovf(_, hop): if hop.s_result.unsigned: raise TyperError("forbidden uint_pow_ovf") + hop.has_implicit_exception(OverflowError) # record that we know about it return self.rtype_pow(_, hop, suffix='_ovf') def rtype_inplace_pow(_, hop): @@ -167,9 +170,13 @@ if func1.endswith('_ovf'): raise TyperError("forbidden uint_" + func) vlist = hop.inputargs(Unsigned, Unsigned) + hop.exception_is_here() return hop.genop('uint_'+func, vlist, resulttype=Unsigned) else: + if func1.endswith('_ovf'): # record that we know about it + hop.has_implicit_exception(OverflowError) vlist = hop.inputargs(Signed, Signed) + hop.exception_is_here() return hop.genop('int_'+func, vlist, resulttype=Signed) #Helper functions for comparisons @@ -233,6 +240,8 @@ raise TyperError("forbidden uint_abs_ovf") else: vlist = hop.inputargs(Signed) + hop.has_implicit_exception(OverflowError) # record we know about it + hop.exception_is_here() return hop.genop('int_abs_ovf', vlist, resulttype=Signed) def rtype_invert(_, hop): @@ -256,6 +265,8 @@ raise TyperError("forbidden uint_neg_ovf") else: vlist = hop.inputargs(Signed) + hop.has_implicit_exception(OverflowError) # record we know about it + hop.exception_is_here() return hop.genop('int_neg_ovf', vlist, resulttype=Signed) def rtype_pos(_, hop): Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Tue Aug 9 16:32:17 2005 @@ -107,6 +107,8 @@ def rtype_method_index(self, hop): v_lst, v_value = hop.inputargs(self, self.item_repr) + hop.has_implicit_exception(ValueError) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_listindex, v_lst, v_value, self.get_eqfunc()) def rtype_method_insert(self, hop): @@ -190,6 +192,7 @@ llfn = ll_getitem_nonneg else: llfn = ll_getitem + hop.exception_is_here() return hop.gendirectcall(llfn, v_lst, v_index) def rtype_setitem((r_lst, r_int), hop): @@ -204,6 +207,7 @@ llfn = ll_setitem_nonneg else: llfn = ll_setitem + hop.exception_is_here() return hop.gendirectcall(llfn, v_lst, v_index, v_item) def rtype_delitem((r_lst, r_int), hop): @@ -218,6 +222,7 @@ llfn = ll_delitem_nonneg else: llfn = ll_delitem + hop.exception_is_here() return hop.gendirectcall(llfn, v_lst, v_index) def rtype_mul((r_lst, r_int), hop): @@ -465,7 +470,7 @@ if i < 0: i += len(l.items) if i >= len(l.items) or i < 0: - raise IndexErrror + raise IndexError ll_delitem_nonneg(l, i) def ll_concat(l1, l2): @@ -716,6 +721,8 @@ def rtype_next(self, hop): v_iter, = hop.inputargs(self) + hop.has_implicit_exception(StopIteration) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_listnext, v_iter) def ll_listiter(ITERPTR, lst): Modified: pypy/dist/pypy/rpython/robject.py ============================================================================== --- pypy/dist/pypy/rpython/robject.py (original) +++ pypy/dist/pypy/rpython/robject.py Tue Aug 9 16:32:17 2005 @@ -51,6 +51,7 @@ def make_operation(opname, cls=PyObjRepr): def rtype_op(_, hop): vlist = hop.inputargs(*([pyobj_repr]*hop.nb_args)) + hop.exception_is_here() if isinstance(hop.r_result, VoidRepr): hop.genop(opname, vlist) else: Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Tue Aug 9 16:32:17 2005 @@ -403,6 +403,7 @@ if self.lowleveltype == Void: assert len(self.function_signatures()) == 1 vlist[0] = hop.inputconst(typeOf(f), f) + hop.exception_is_here() v = hop.genop('direct_call', vlist, resulttype = rresult) return hop.llops.convertvar(v, rresult, hop.r_result) Modified: pypy/dist/pypy/rpython/rptr.py ============================================================================== --- pypy/dist/pypy/rpython/rptr.py (original) +++ pypy/dist/pypy/rpython/rptr.py Tue Aug 9 16:32:17 2005 @@ -55,6 +55,7 @@ if not isinstance(self.lowleveltype.TO, FuncType): raise TyperError("calling a non-function %r", self.lowleveltype.TO) vlist = hop.inputargs(*hop.args_r) + hop.exception_is_here() return hop.genop('direct_call', vlist, resulttype = self.lowleveltype.TO.RESULT) Modified: pypy/dist/pypy/rpython/rrange.py ============================================================================== --- pypy/dist/pypy/rpython/rrange.py (original) +++ pypy/dist/pypy/rpython/rrange.py Tue Aug 9 16:32:17 2005 @@ -43,6 +43,7 @@ llfn = ll_rangeitem_nonneg else: llfn = ll_rangeitem + hop.exception_is_here() return hop.gendirectcall(llfn, v_lst, v_index, cstep) # ____________________________________________________________ @@ -120,6 +121,8 @@ llfn = ll_rangenext_up else: llfn = ll_rangenext_down + hop.has_implicit_exception(StopIteration) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(llfn, v_iter, cstep) def ll_rangeiter(ITERPTR, rng): Modified: pypy/dist/pypy/rpython/rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/rspecialcase.py (original) +++ pypy/dist/pypy/rpython/rspecialcase.py Tue Aug 9 16:32:17 2005 @@ -25,4 +25,5 @@ def rtype_override_ignore(hop, clsdef): # ignore works for methods too + hop.exception_cannot_occur() return inputconst(hop.r_result, None) Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Tue Aug 9 16:32:17 2005 @@ -157,13 +157,16 @@ return hop.gendirectcall(ll_replace_chr_chr, v_str, v_c1, v_c2) def rtype_int(_, hop): + hop.has_implicit_exception(ValueError) # record that we know about it if hop.nb_args == 1: v_str, = hop.inputargs(string_repr) c_base = inputconst(Signed, 10) + hop.exception_is_here() return hop.gendirectcall(ll_int, v_str, c_base) if not hop.args_r[1] == rint.signed_repr: raise TyperError, 'base needs to be an int' v_str, v_base= hop.inputargs(string_repr, rint.signed_repr) + hop.exception_is_here() return hop.gendirectcall(ll_int, v_str, v_base) def ll_str(s, r): @@ -189,6 +192,7 @@ llfn = ll_stritem_nonneg else: llfn = ll_stritem + hop.exception_is_here() return hop.gendirectcall(llfn, v_str, v_index) def rtype_mod(_, hop): @@ -936,6 +940,8 @@ def rtype_next(self, hop): v_iter, = hop.inputargs(self) + hop.has_implicit_exception(StopIteration) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_strnext, v_iter) string_iterator_repr = StringIteratorRepr() Modified: pypy/dist/pypy/rpython/rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/rtuple.py (original) +++ pypy/dist/pypy/rpython/rtuple.py Tue Aug 9 16:32:17 2005 @@ -196,6 +196,8 @@ def rtype_next(self, hop): v_iter, = hop.inputargs(self) + hop.has_implicit_exception(StopIteration) # record that we know about it + hop.exception_is_here() return hop.gendirectcall(ll_tuplenext, v_iter) def ll_tupleiter(ITERPTR, tuple): Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Tue Aug 9 16:32:17 2005 @@ -261,6 +261,33 @@ block.operations[:] = newops block.renamevariables(varmapping) + + pos = newops.llop_raising_exceptions + if (pos is not None and pos != len(newops)-1): + # this is for the case where the llop that raises the exceptions + # is not the last one in the list. + assert block.exitswitch == Constant(last_exception) + noexclink = block.exits[0] + assert noexclink.exitcase is None + if pos == "removed": + # the exception cannot actually occur at all. + # See for example rspecialcase.rtype_call_specialcase(). + # We just remove all exception links. + block.exitswitch = None + block.exits = block.exits[:1] + else: + # We have to split the block in two, with the exception-catching + # exitswitch after the llop at 'pos', and the extra operations + # in the new part of the block, corresponding to the + # no-exception case. See for example test_rlist.test_indexerror + # or test_rpbc.test_multiple_ll_one_hl_op. + assert 0 <= pos < len(newops) - 1 + extraops = block.operations[pos+1:] + del block.operations[pos+1:] + insert_empty_block(self.annotator.translator, + noexclink, + newops = extraops) + self.insert_link_conversions(block) def insert_link_conversions(self, block): @@ -346,6 +373,11 @@ def translate_hl_to_ll(self, hop, varmapping): log.translating(hop.spaceop.opname, hop.args_s) resultvar = hop.dispatch() + if hop.exceptionlinks and hop.llops.llop_raising_exceptions is None: + raise TyperError("the graph catches %s, but the rtyper did not " + "take exceptions into account " + "(exception_is_here() not called)" % ( + [link.exitcase.__name__ for link in hop.exceptionlinks],)) op = hop.spaceop if resultvar is None: # no return value @@ -590,17 +622,54 @@ self.args_r[0], self.args_r[1] = self.args_r[1], self.args_r[0] def has_implicit_exception(self, exc_cls): + if self.llops.llop_raising_exceptions is not None: + raise TyperError("already generated the llop that raises the " + "exception") + if not self.exceptionlinks: + return False # don't record has_implicit_exception checks on + # high-level ops before the last one in the block + if self.llops.implicit_exceptions_checked is None: + self.llops.implicit_exceptions_checked = [] for link in self.exceptionlinks: if issubclass(exc_cls, link.exitcase): + self.llops.implicit_exceptions_checked.append(link.exitcase) return True return False + def exception_is_here(self): + if self.llops.llop_raising_exceptions is not None: + raise TyperError("cannot catch an exception at more than one llop") + if not self.exceptionlinks: + return # ignored for high-level ops before the last one in the block + if self.llops.implicit_exceptions_checked is not None: + # sanity check: complain if an has_implicit_exception() check is + # missing in the rtyper. + for link in self.exceptionlinks: + if link.exitcase not in self.llops.implicit_exceptions_checked: + raise TyperError("the graph catches %s, but the rtyper " + "did not explicitely handle it" % ( + link.exitcase.__name__,)) + self.llops.llop_raising_exceptions = len(self.llops) + + def exception_cannot_occur(self): + if self.llops.llop_raising_exceptions is not None: + raise TyperError("cannot catch an exception at more than one llop") + if not self.exceptionlinks: + return # ignored for high-level ops before the last one in the block + self.llops.llop_raising_exceptions = "removed" + # ____________________________________________________________ class LowLevelOpList(list): """A list with gen*() methods to build and append low-level operations to it. """ + # NB. the following two attributes are here instead of on HighLevelOp + # because we want them to be shared between a HighLevelOp and its + # copy()es. + llop_raising_exceptions = None + implicit_exceptions_checked = None + def __init__(self, rtyper): self.rtyper = rtyper Modified: pypy/dist/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rlist.py (original) +++ pypy/dist/pypy/rpython/test/test_rlist.py Tue Aug 9 16:32:17 2005 @@ -382,3 +382,19 @@ for arg in (1, 9, 0, -1, -27): res = interpret(fn, [arg]) assert res == fn(arg) + +def test_indexerror(): + def fn(i): + l = [5, 8, 3] + try: + del l[i] + except IndexError: + pass + try: + return l[2] # implicit int->PyObj conversion here + except IndexError: + return "oups" + res = interpret(fn, [6]) + assert res._obj.value == 3 + res = interpret(fn, [-2]) + assert res._obj.value == "oups" Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Tue Aug 9 16:32:17 2005 @@ -790,7 +790,7 @@ assert res == 3*2+11*7 -def test_mulitple_ll_one_hl_op(): +def test_multiple_ll_one_hl_op(): class E(Exception): pass class A(object): @@ -822,9 +822,4 @@ return c.method(x + 1) except E: return None - try: - res = interpret(call, [0]) - except: - py.test.skip("this test shows the problem with rtyping exceptions") - - + res = interpret(call, [0]) From pedronis at codespeak.net Tue Aug 9 16:43:02 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 9 Aug 2005 16:43:02 +0200 (CEST) Subject: [pypy-svn] r15822 - pypy/dist/pypy/lib/test2 Message-ID: <20050809144302.EBE6827B48@code1.codespeak.net> Author: pedronis Date: Tue Aug 9 16:43:02 2005 New Revision: 15822 Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py Log: fall-back so that this test (which is run on top of CPython) can pass on 2.3 too Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_deque_extra.py (original) +++ pypy/dist/pypy/lib/test2/test_deque_extra.py Tue Aug 9 16:43:02 2005 @@ -1,6 +1,11 @@ # Deque Tests - +# for passing the test on top of 2.3 +try: + reversed +except NameError: + def reversed(seq): # fall-back + return seq.__reversed__() n = 10 class Test_deque: @@ -14,7 +19,7 @@ assert len(self.d) == n for i in range(n): assert i == self.d[i] - for i in reversed(range(n)): + for i in range(n-1, -1, -1): assert self.d.pop() == i def test_deque_iter(self): @@ -35,4 +40,4 @@ self.d.pop() raises(RuntimeError,it.next) assert len(it) == 0 - assert list(it) == [] \ No newline at end of file + assert list(it) == [] From adim at codespeak.net Tue Aug 9 16:48:10 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Tue, 9 Aug 2005 16:48:10 +0200 (CEST) Subject: [pypy-svn] r15824 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050809144810.6653627B48@code1.codespeak.net> Author: adim Date: Tue Aug 9 16:48:09 2005 New Revision: 15824 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Log: hackish workaround to make test pass even if empty lists are used instead of empty tuples in stablecompiler Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_samples.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Tue Aug 9 16:48:09 2005 @@ -104,8 +104,16 @@ # XXX hack: # hide the more common difference between 2.3 and 2.4, which is # Function(None, ...) where 'None' stands for no decorator in 2.4 - repr_pypy = repr_pypy .replace("Function(None, ", "Function(") + repr_pypy = repr_pypy.replace("Function(None, ", "Function(") repr_python = repr_python.replace("Function(None, ", "Function(") + # XXX hack(bis): + # we changed stablecompiler to use [] instead of () in several + # places (for consistency), so let's make sure the test won't fail + # because of that (the workaround is as drastic as the way we + # compare python and pypy tuples :-), but we'll change that with + # astbuilder.py + repr_pypy = repr_pypy.replace("[]", "()") + repr_python = repr_python.replace("[]", "()") assert repr_pypy == repr_python From cfbolz at codespeak.net Tue Aug 9 17:00:09 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 17:00:09 +0200 (CEST) Subject: [pypy-svn] r15828 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050809150009.9FE3E27B4D@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 17:00:08 2005 New Revision: 15828 Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: unify interpret and interpret_raises Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Tue Aug 9 17:00:08 2005 @@ -39,7 +39,8 @@ _lastinterpreted = [] _tcache = {} -def interpret(func, values, view=False, viewbefore=False, policy=None, someobjects=False): +def get_interpreter(func, values, view=False, viewbefore=False, policy=None, + someobjects=False): key = (func,) + tuple([typeOf(x) for x in values])+ (someobjects,) try: (t, interp) = _tcache[key] @@ -64,33 +65,17 @@ del _tcache[_lastinterpreted.pop(0)] if view: t.view() + return interp + +def interpret(func, values, view=False, viewbefore=False, policy=None, + someobjects=False): + interp = get_interpreter(func, values, view, viewbefore, policy, + someobjects) return interp.eval_function(func, values) def interpret_raises(exc, func, values, view=False, viewbefore=False, policy=None, someobjects=False): - key = (func,) + tuple([typeOf(x) for x in values])+ (someobjects,) - try: - (t, interp) = _tcache[key] - except KeyError: - def annotation(x): - T = typeOf(x) - if T == Ptr(PyObject) and someobjects: - return object - elif T == Ptr(rstr.STR): - return str - else: - return lltype_to_annotation(T) - - t, typer = gengraph(func, [annotation(x) - for x in values], viewbefore, policy) - interp = LLInterpreter(t.flowgraphs, typer, gclltype, - gclltype.prepare_graphs) - _tcache[key] = (t, interp) - # keep the cache small - _lastinterpreted.append(key) - if len(_lastinterpreted) >= 4: - del _tcache[_lastinterpreted.pop(0)] - if view: - t.view() + interp = get_interpreter(func, values, view, viewbefore, policy, + someobjects) info = py.test.raises(LLException, "interp.eval_function(func, values)") assert find_exception(info.value, interp) is exc, "wrong exception type" From arigo at codespeak.net Tue Aug 9 17:10:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 17:10:46 +0200 (CEST) Subject: [pypy-svn] r15832 - pypy/dist/pypy/documentation Message-ID: <20050809151046.2203B27B4D@code1.codespeak.net> Author: arigo Date: Tue Aug 9 17:10:39 2005 New Revision: 15832 Modified: pypy/dist/pypy/documentation/translation.txt Log: Documentation about the interface of HighLevelOp, with a part taken from my previous check-in message. Modified: pypy/dist/pypy/documentation/translation.txt ============================================================================== --- pypy/dist/pypy/documentation/translation.txt (original) +++ pypy/dist/pypy/documentation/translation.txt Tue Aug 9 17:10:39 2005 @@ -833,6 +833,93 @@ See for example `rpython/rlist.py`_. +HighLevelOp interface ++++++++++++++++++++++ + +In the absence of more extensive documentation about how RPython types are +implemented, here is the interface and intended usage of the 'hop' +argument that appears everywhere. A 'hop' is a HighLevelOp instance, +which represents a single high-level operation that must be turned into +one or several low-level operations. + + ``hop.llops`` + A list-like object that records the low-level operations that + correspond to the current block's high-level operations. + + ``hop.genop(opname, list_of_variables, resulttype=resulttype)`` + Append a low-level operation to ``hop.llops``. The operation has + the given opname and arguments, and returns the given low-level + resulttype. The arguments should come from the ``hop.input*()`` + functions described below. + + ``hop.gendirectcall(ll_function, var1, var2...)`` + Like hop.genop(), but produces a ``direct_call`` operation that + invokes the given low-level function, which is automatically + annotated with low-level types based on the input arguments. + + ``hop.inputargs(r1, r2...)`` + Reads the high-level Variables and Constants that are the + arguments of the operation, and convert them if needed so that + they have the specified representations. You must provide as many + representations as the operation has arguments. Returns a list of + (possibly newly converted) Variables and Constants. + + ``hop.inputarg(r, arg=i)`` + Same as inputargs(), but only converts and returns the ith + argument. + + ``hop.inputconst(lltype, value)`` + Returns a Constant with a low-level type and value. + +Manipulation of HighLevelOp instances (this is used e.g. to insert a +'self' implicit argument to translate method calls): + + ``hop.copy()`` + Returns a fresh copy that can be manipulated with the functions + below. + + ``hop.r_s_popfirstarg()`` + Removes the first argument of the high-level operation. This + doesn't really changes the source SpaceOperation, but modifies + 'hop' in such a way that methods like inputargs() no longer see + the removed argument. + + ``hop.v_s_insertfirstarg(v_newfirstarg, s_newfirstarg)`` + Insert an argument in front of the hop. It must be specified by + a Variable (as in calls to hop.genop()) and a corresponding + annotation. + + ``hop.swap_fst_snd_args()`` + Self-descriptive. + +Exception handling: + + ``hop.has_implicit_exception(cls)`` + Checks if hop is in the scope of a branch catching the exception + 'cls'. This is useful for high-level operations like 'getitem' + that have several low-level equivalents depending on whether they + should check for an IndexError or not. Calling + has_implicit_exception() also has a side-effect: the rtyper + records that this exception is being taken care of explicitely. + + ``hop.exception_is_here()`` + To be called with no argument just before a llop is generated. It + means that the llop in question will be the one that should be + protected by the exception catching. If has_implicit_exception() + was called before, then exception_is_here() verifies that *all* + except links in the graph have indeed been checked for with an + has_implicit_exception(). This is not verified if + has_implicit_exception() has never been called -- useful for + 'direct_call' and other operations that can just raise any exception. + + ``hop.exception_cannot_occur()`` + A special case for ``override:ignore`` meaning that there is, after + all, no operation left that could raise an exception. (The RTyper + class normally verifies that exception_is_here() was really called + once for each high-level operation that is in the scope of + exception-catching links.) + + .. _C: .. _GenC: From arigo at codespeak.net Tue Aug 9 17:19:01 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 17:19:01 +0200 (CEST) Subject: [pypy-svn] r15834 - pypy/dist/pypy/translator/test Message-ID: <20050809151901.99FB527B4D@code1.codespeak.net> Author: arigo Date: Tue Aug 9 17:18:58 2005 New Revision: 15834 Modified: pypy/dist/pypy/translator/test/test_annrpython.py Log: Fixed tests to expect the more precise 'can_only_throw' tags on getitem. Modified: pypy/dist/pypy/translator/test/test_annrpython.py ============================================================================== --- pypy/dist/pypy/translator/test/test_annrpython.py (original) +++ pypy/dist/pypy/translator/test/test_annrpython.py Tue Aug 9 17:18:58 2005 @@ -671,7 +671,7 @@ a = self.RPythonAnnotator() s = a.build_types(f, [list]) - assert s.knowntype is LookupError + assert s.knowntype is IndexError # KeyError ignored because l is a list def test_overrides(self): import sys @@ -1100,8 +1100,9 @@ t = annmodel.SomeObject() t.knowntype = type t.is_type_of = [ev] + t.const = KeyError # IndexError ignored because 'dic' is a dict assert a.binding(et) == t - assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef.cls == LookupError + assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef.cls == KeyError def test_exception_mixing(self): def h(): From adim at codespeak.net Tue Aug 9 17:24:43 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Tue, 9 Aug 2005 17:24:43 +0200 (CEST) Subject: [pypy-svn] r15835 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050809152443.4FBF427B46@code1.codespeak.net> Author: adim Date: Tue Aug 9 17:24:40 2005 New Revision: 15835 Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_while.py Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_import_statements.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - implemented while stmts - implemented import statements Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Tue Aug 9 17:24:40 2005 @@ -513,6 +513,107 @@ builder.push(ast.For(assign, iterable, body, else_)) +def build_while_stmt(builder, nb): + """while_stmt: 'while' test ':' suite ['else' ':' suite]""" + L = get_atoms(builder, nb) + else_ = None + # skip 'while' + test = L[1] + # skip ':' + body = L[3] + # if there is a "else" statement + if len(L) > 4: + # skip 'else' and ':' + else_ = L[6] + builder.push(ast.While(test, body, else_)) + + +def build_import_name(builder, nb): + """import_name: 'import' dotted_as_names + + dotted_as_names: dotted_as_name (',' dotted_as_name)* + dotted_as_name: dotted_name [NAME NAME] + dotted_name: NAME ('.' NAME)* + + written in an unfolded way: + 'import' NAME(.NAME)* [NAME NAME], (NAME(.NAME)* [NAME NAME],)* + + XXX: refactor build_import_name and build_import_from + """ + L = get_atoms(builder, nb) + index = 1 # skip 'import' + l = len(L) + names = [] + while index < l: + as_name = None + # dotted name (a.b.c) + incr, name = parse_dotted_names(L[index:]) + index += incr + # 'as' value + if index < l and L[index].value == 'as': + as_name = L[index+1].value + index += 2 + names.append((name, as_name)) + # move forward until next ',' + while index < l and L[index].name != tok.COMMA: + index += 1 + index += 1 + builder.push(ast.Import(names)) + + +def build_import_from(builder, nb): + """ + import_from: 'from' dotted_name 'import' ('*' | '(' import_as_names ')' | import_as_names) + + import_as_names: import_as_name (',' import_as_name)* [','] + import_as_name: NAME [NAME NAME] + """ + L = get_atoms(builder, nb) + index = 1 + incr, from_name = parse_dotted_names(L[index:]) + index += (incr + 1) # skip 'import' + if L[index].name == tok.STAR: + names = [('*', None)] + else: + if L[index].name == tok.LPAR: + # mutli-line imports + tokens = L[index+1:-1] + else: + tokens = L[index:] + index = 0 + l = len(tokens) + names = [] + while index < l: + name = tokens[index].value + as_name = None + index += 1 + if index < l: + if tokens[index].value == 'as': + as_name = tokens[index+1].value + index += 2 + names.append((name, as_name)) + if index < l: # case ',' + index += 1 + builder.push(ast.From(from_name, names)) + + +def parse_dotted_names(tokens): + """parses NAME('.' NAME)* and returns full dotted name + + this function doesn't assume that the list ends after the + last 'NAME' element + """ + name = tokens[0].value + l = len(tokens) + index = 1 + for index in range(1, l, 2): + token = tokens[index] + assert isinstance(token, TokenObject) + if token.name != tok.DOT: + break + name = name + '.' + tokens[index+1].value + return (index, name) + def parse_argument(tokens): """parses function call arguments""" l = len(tokens) @@ -693,6 +794,9 @@ sym.pass_stmt : build_pass_stmt, sym.break_stmt : build_break_stmt, sym.for_stmt : build_for_stmt, + sym.while_stmt : build_while_stmt, + sym.import_name : build_import_name, + sym.import_from : build_import_from, # sym.parameters : build_parameters, } Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_import_statements.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_import_statements.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_import_statements.py Tue Aug 9 17:24:40 2005 @@ -1,2 +1,5 @@ import os import os.path as osp +from sets import Set, ImmutableSet + + Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_while.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_while.py Tue Aug 9 17:24:40 2005 @@ -0,0 +1,8 @@ +index = 0 +while index < 10: + index += 1 + foo = 10 - index + if False: + break +else: + foo = 12 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Tue Aug 9 17:24:40 2005 @@ -100,6 +100,24 @@ 'x = a.b', ] +imports = [ + 'import os', + 'import sys, os', + 'import os.path', + 'import os.path, sys', + 'import sys, os.path as osp', + 'import os.path as osp', + 'import os.path as osp, sys as _sys', + 'import a.b.c.d', + 'import a.b.c.d as abcd', + 'from os import path', + 'from os import path, system', + 'from os import path, system,', + 'from os import path as P, system as S,', + 'from os import (path as P, system as S,)', + 'from os import *', + ] + if_stmts = [ "if a == 1: a+= 2", """if a == 1: @@ -133,6 +151,7 @@ dictmakers, multiexpr, attraccess, + imports, ] EXEC_INPUTS = [ @@ -183,6 +202,8 @@ 'snippet_several_statements.py', 'snippet_simple_function.py', 'snippet_simple_for_loop.py', + 'snippet_while.py', + 'snippet_import_statements.py', # 'snippet_2.py', # 'snippet_3.py', # 'snippet_4.py', From cfbolz at codespeak.net Tue Aug 9 17:26:43 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 17:26:43 +0200 (CEST) Subject: [pypy-svn] r15836 - in pypy/dist/pypy/rpython: memory/test test Message-ID: <20050809152643.8639727B46@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 17:26:42 2005 New Revision: 15836 Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py pypy/dist/pypy/rpython/test/test_llinterp.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/rpython/test/test_rstr.py Log: change the way test_llinterp handles interpreted functions that are supposed to raise exceptions: there is now a new function interpret_raises(exc, function, [args]) that asserts that interpreting a function raises the given exception. This doesn't work for user defined exceptions. Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Tue Aug 9 17:26:42 2005 @@ -12,10 +12,7 @@ from pypy.rpython.memory.lltypesimulation import pyobjectptr from pypy.rpython.memory import gclltype -from pypy.rpython.test.test_llinterp import timelog, gengraph -from pypy.rpython.test import test_llinterp - -# switch on logging of interp to show more info on failing tests +from pypy.rpython.test.test_llinterp import timelog, gengraph, find_exception def setup_module(mod): mod.logstate = py.log._getstate() @@ -25,18 +22,6 @@ py.log._setstate(mod.logstate) -def find_exception(exc, interp): - assert isinstance(exc, LLException) - import exceptions - klass, inst = exc.args - func = test_llinterp.typer.getexceptiondata().ll_pyexcclass2exc - for cls in exceptions.__dict__.values(): - if type(cls) is type(Exception): - if interp.eval_function(func, [pyobjectptr(cls)]).typeptr == klass: - return cls - raise ValueError, "couldn't match exception" - - _lastinterpreted = [] _tcache = {} def get_interpreter(func, values, view=False, viewbefore=False, policy=None, Modified: pypy/dist/pypy/rpython/test/test_llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_llinterp.py (original) +++ pypy/dist/pypy/rpython/test/test_llinterp.py Tue Aug 9 17:26:42 2005 @@ -19,15 +19,18 @@ def teardown_module(mod): py.log._setstate(mod.logstate) -def find_exception(exc): + +def find_exception(exc, interp): assert isinstance(exc, LLException) import exceptions klass, inst = exc.args func = typer.getexceptiondata().ll_pyexcclass2exc for cls in exceptions.__dict__.values(): if type(cls) is type(Exception): - if func(pyobjectptr(cls)).typeptr == klass: + if interp.eval_function(func, [pyobjectptr(cls)]).typeptr == klass: return cls + raise ValueError, "couldn't match exception" + def timelog(prefix, call, *args, **kwds): #import time @@ -54,7 +57,7 @@ _lastinterpreted = [] _tcache = {} -def interpret(func, values, view=False, viewbefore=False, policy=None, someobjects=False): +def get_interpreter(func, values, view=False, viewbefore=False, policy=None, someobjects=False): key = (func,) + tuple([typeOf(x) for x in values])+ (someobjects,) try: (t, interp) = _tcache[key] @@ -78,8 +81,20 @@ del _tcache[_lastinterpreted.pop(0)] if view: t.view() + return interp + +def interpret(func, values, view=False, viewbefore=False, policy=None, + someobjects=False): + interp = get_interpreter(func, values, view, viewbefore, policy, + someobjects) return interp.eval_function(func, values) +def interpret_raises(exc, func, values, view=False, viewbefore=False, policy=None, someobjects=False): + interp = get_interpreter(func, values, view, viewbefore, policy, + someobjects) + info = py.test.raises(LLException, "interp.eval_function(func, values)") + assert find_exception(info.value, interp) is exc, "wrong exception type" + #__________________________________________________________________ # tests @@ -107,38 +122,30 @@ def test_raise(): res = interpret(raise_exception, [41]) assert res == 41 - info = raises(LLException, interpret, raise_exception, [42]) - assert find_exception(info.value) is IndexError - info = raises(LLException, interpret, raise_exception, [43]) - assert find_exception(info.value) is ValueError + interpret_raises(IndexError, raise_exception, [42]) + interpret_raises(ValueError, raise_exception, [43]) def test_call_raise(): res = interpret(call_raise, [41]) assert res == 41 - info = raises(LLException, interpret, call_raise, [42]) - assert find_exception(info.value) is IndexError - info = raises(LLException, interpret, call_raise, [43]) - assert find_exception(info.value) is ValueError + interpret_raises(IndexError, call_raise, [42]) + interpret_raises(ValueError, call_raise, [43]) def test_call_raise_twice(): res = interpret(call_raise_twice, [6, 7]) assert res == 13 - info = raises(LLException, interpret, call_raise_twice, [6, 42]) - assert find_exception(info.value) is IndexError + interpret_raises(IndexError, call_raise_twice, [6, 42]) res = interpret(call_raise_twice, [6, 43]) assert res == 1006 - info = raises(LLException, interpret, call_raise_twice, [42, 7]) - assert find_exception(info.value) is IndexError - info = raises(LLException, interpret, call_raise_twice, [43, 7]) - assert find_exception(info.value) is ValueError + interpret_raises(IndexError, call_raise_twice, [42, 7]) + interpret_raises(ValueError, call_raise_twice, [43, 7]) def test_call_raise_intercept(): res = interpret(call_raise_intercept, [41], view=False) assert res == 41 res = interpret(call_raise_intercept, [42]) assert res == 42 - info = raises(LLException, interpret, call_raise_intercept, [43]) - assert find_exception(info.value) is TypeError + interpret_raises(TypeError, call_raise_intercept, [43]) def test_while_simple(): res = interpret(while_simple, [3]) Modified: pypy/dist/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rlist.py (original) +++ pypy/dist/pypy/rpython/test/test_rlist.py Tue Aug 9 17:26:42 2005 @@ -4,8 +4,7 @@ from pypy.rpython.rlist import * from pypy.rpython.rslice import ll_newslice from pypy.rpython.rint import signed_repr -from pypy.rpython.test.test_llinterp import interpret -from pypy.rpython.test.test_llinterp import find_exception +from pypy.rpython.test.test_llinterp import interpret, interpret_raises def sample_list(): # [42, 43, 44, 45] @@ -322,14 +321,11 @@ return lis.index(args[i]) for i in range(4): try: - res = interpret(fn, [i]) - except Exception, e: - res = find_exception(e) - try: res2 = fn(i) + res1 = interpret(fn, [i]) + assert res1 == res2 except Exception, e: - res2 = e.__class__ - assert res == res2 + interpret_raises(e.__class__, fn, [i]) def test_list_str(): def fn(): Modified: pypy/dist/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rstr.py (original) +++ pypy/dist/pypy/rpython/test/test_rstr.py Tue Aug 9 17:26:42 2005 @@ -2,7 +2,7 @@ from pypy.rpython.lltype import * from pypy.rpython.rstr import parse_fmt_string from pypy.rpython.rtyper import RPythonTyper, TyperError -from pypy.rpython.test.test_llinterp import interpret,find_exception +from pypy.rpython.test.test_llinterp import interpret, interpret_raises from pypy.rpython.llinterp import LLException def test_simple(): @@ -410,8 +410,7 @@ try: expected = fn(i, j) except ValueError: - info = raises(LLException, interpret, fn, [i, j]) - assert find_exception(info.value) is ValueError + interpret_raises(ValueError, fn, [i, j]) else: res = interpret(fn, [i, j]) assert res == expected From adim at codespeak.net Tue Aug 9 17:46:39 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Tue, 9 Aug 2005 17:46:39 +0200 (CEST) Subject: [pypy-svn] r15839 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050809154639.971E527B46@code1.codespeak.net> Author: adim Date: Tue Aug 9 17:46:37 2005 New Revision: 15839 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - implemented yield / continue - partially implemented del statements (only for "del name") Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Tue Aug 9 17:46:37 2005 @@ -452,7 +452,9 @@ elif len(L) == 4: # Only one statement for (stmt+) stmt = L[2] - builder.push(L[2]) + if not isinstance(stmt, ast.Stmt): + stmt = ast.Stmt([stmt]) + builder.push(stmt) else: # several statements stmts = [] @@ -597,6 +599,19 @@ builder.push(ast.From(from_name, names)) +def build_yield_stmt(builder, nb): + L = get_atoms(builder, nb) + builder.push(ast.Yield(L[1])) + +def build_continue_stmt(builder, nb): + L = get_atoms(builder, nb) + builder.push(ast.Continue()) + +def build_del_stmt(builder, nb): + L = get_atoms(builder, nb) + assert isinstance(L[1], ast.Name), "build_del_stmt implementation is incomplete !" + builder.push(ast.AssName(L[1].name, consts.OP_DELETE)) + def parse_dotted_names(tokens): """parses NAME('.' NAME)* and returns full dotted name @@ -797,6 +812,9 @@ sym.while_stmt : build_while_stmt, sym.import_name : build_import_name, sym.import_from : build_import_from, + sym.yield_stmt : build_yield_stmt, + sym.continue_stmt : build_continue_stmt, + sym.del_stmt : build_del_stmt, # sym.parameters : build_parameters, } Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py Tue Aug 9 17:46:37 2005 @@ -6,6 +6,8 @@ b += 2 if False: break + else: + continue else: c = 3 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Tue Aug 9 17:46:37 2005 @@ -24,6 +24,8 @@ "x = a * (1 + c)", "x, y, z = 1, 2, 3", "x = 'a' 'b' 'c'", + "del foo", + # "del foo[bar]", ] funccalls = [ @@ -204,6 +206,7 @@ 'snippet_simple_for_loop.py', 'snippet_while.py', 'snippet_import_statements.py', + 'snippet_generator.py', # 'snippet_2.py', # 'snippet_3.py', # 'snippet_4.py', @@ -212,7 +215,6 @@ # 'snippet_encoding_declaration3.py', # 'snippet_encoding_declaration.py', # 'snippet_function_calls.py', -# 'snippet_generator.py', # 'snippet_import_statements.py', # 'snippet_list_comps.py', # 'snippet_multiline.py', From cfbolz at codespeak.net Tue Aug 9 18:09:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 18:09:16 +0200 (CEST) Subject: [pypy-svn] r15844 - in pypy/dist/pypy/rpython: memory memory/test test Message-ID: <20050809160916.D53D127B48@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 18:09:16 2005 New Revision: 15844 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py pypy/dist/pypy/rpython/test/test_llinterp.py Log: do not convert void arguments :-( Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Tue Aug 9 18:09:16 2005 @@ -8,6 +8,8 @@ from pypy.objspace.flow.model import Constant from pypy.rpython import lltype +from pypy.rpython.rmodel import IntegerRepr + import types, struct class LLTypeConverter(object): @@ -118,12 +120,15 @@ constants = {} def collect_args(args): for arg in args: - if isinstance(arg, Constant): + if (isinstance(arg, Constant) and + arg.concretetype is not lltype.Void): constants[arg] = None def visit(obj): if isinstance(obj, Link): collect_args(obj.args) if hasattr(obj, "llexitcase"): + if isinstance(obj.llexitcase, IntegerRepr): + assert 0 constants[Constant(obj.llexitcase)] = None elif isinstance(obj, Block): for op in obj.operations: Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Tue Aug 9 18:09:16 2005 @@ -369,6 +369,23 @@ return i except ValueError: raise TypeError + + +#the following function has a constant argument which is void +def test_str_of_int(): + def dummy(i): + return str(i) + + res = interpret(dummy, [0]) + assert ''.join(res.chars) == '0' + + res = interpret(dummy, [1034]) + assert ''.join(res.chars) == '1034' + + res = interpret(dummy, [-123]) + assert ''.join(res.chars) == '-123' + + #__________________________________________________________________ # interactive playing Modified: pypy/dist/pypy/rpython/test/test_llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_llinterp.py (original) +++ pypy/dist/pypy/rpython/test/test_llinterp.py Tue Aug 9 18:09:16 2005 @@ -9,6 +9,7 @@ from pypy.rpython import rstr from pypy.annotation.model import lltype_to_annotation from pypy.rpython.rarithmetic import r_uint, ovfcheck +from pypy.rpython.memory import gclltype # switch on logging of interp to show more info on failing tests @@ -73,7 +74,8 @@ t, typer = gengraph(func, [annotation(x) for x in values], viewbefore, policy) - interp = LLInterpreter(t.flowgraphs, typer) + interp = LLInterpreter(t.flowgraphs, typer, gclltype, + gclltype.prepare_graphs) _tcache[key] = (t, interp) # keep the cache small _lastinterpreted.append(key) From arigo at codespeak.net Tue Aug 9 18:20:07 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 18:20:07 +0200 (CEST) Subject: [pypy-svn] r15846 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20050809162007.98D4327B48@code1.codespeak.net> Author: arigo Date: Tue Aug 9 18:20:03 2005 New Revision: 15846 Modified: pypy/dist/pypy/module/__builtin__/__init__.py pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/module/__builtin__/operation.py pypy/dist/pypy/module/__builtin__/test/test_functional.py Log: Reverted rev 15785: * xrange must not be its own iterator. The reason is made explicit in a new test. Note that xrange iterators don't need to have a __len__; they don't in CPython. * pypy.objspace.std cannot be imported from module/, which must not depend on a particular object space. Similarily, space.lookup() is not a general- purpose space operation, it is an internal detail of DescrOperation object spaces. (I'll try to provide a __len__ for reversed() iterators directly at app-level, in the next check-in.) Modified: pypy/dist/pypy/module/__builtin__/__init__.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/__init__.py (original) +++ pypy/dist/pypy/module/__builtin__/__init__.py Tue Aug 9 18:20:03 2005 @@ -28,7 +28,7 @@ 'enumerate' : 'app_functional.enumerate', 'xrange' : 'app_functional.xrange', 'sorted' : 'app_functional.sorted', - #'reversed' : 'app_functional.reversed', + 'reversed' : 'app_functional.reversed', 'issubclass' : 'app_inspect.issubclass', 'isinstance' : 'app_inspect.isinstance', @@ -79,7 +79,6 @@ '_isfake' : 'special._isfake', # interp-level function definitions - 'reversed' : 'operation.interp_reversed', 'abs' : 'operation.abs', 'chr' : 'operation.chr', 'unichr' : 'operation.unichr', Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Tue Aug 9 18:20:03 2005 @@ -282,8 +282,7 @@ n = get_len_of_range(stop, start, -step) self.start = start self.len = n - self.step = step - self.index = 0 + self.step = step def __str__(self): stop = self.start + self.len * self.step @@ -297,7 +296,7 @@ __repr__ = __str__ def __len__(self): - return self.len - self.index + return self.len def __getitem__(self, index): # xrange does NOT support slicing @@ -311,16 +310,10 @@ raise IndexError, "xrange object index out of range" def __iter__(self): - return self - - def next(self): - #i = 0 - if self.index < self.len: - res = self.start + self.index * self.step - self.index += 1 - return res - else: - raise StopIteration + i = 0 + while i < self.len: + yield self.start + i * self.step + i += 1 # ____________________________________________________________ @@ -330,3 +323,16 @@ sorted_lst.sort(cmp, key, reverse) return sorted_lst +def reversed(iterable): + """reversed(sequence) -> reverse iterator over values of the sequence + + Return a reverse iterator + """ + if hasattr(iterable, '__reversed__'): + return iterable.__reversed__() + seq = list(iterable) + def reversed_gen(local_iterable): + len_iterable = len(local_iterable) + for index in range(len_iterable-1, -1, -1): + yield local_iterable[index] + return reversed_gen(seq) Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Tue Aug 9 18:20:03 2005 @@ -7,25 +7,6 @@ from pypy.interpreter.error import OperationError NoneNotWrapped = gateway.NoneNotWrapped - -from pypy.objspace.std.iterobject import W_SeqIterObject - -def interp_reversed(space,w_iterable): - # if obj has __reversed__ call and return it - - func = space.lookup(w_iterable,'__reversed__') - if func : - return space.call_function(func,w_iterable) - # else return W_IterObject with reverse set - else: - - getitem = space.lookup(w_iterable,'__getitem__') - len = space.lookup(w_iterable,'__len__') - if getitem and len : - w_seq = W_SeqIterObject(space,w_iterable,-1,True) - return w_seq - raise OperationError(space.wrap(TypeError),space.wrap('argument to reversed() must be a sequence')) - def abs(space, w_val): "abs(number) -> number\n\nReturn the absolute value of the argument." return space.abs(w_val) Modified: pypy/dist/pypy/module/__builtin__/test/test_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_functional.py Tue Aug 9 18:20:03 2005 @@ -89,3 +89,12 @@ def test_function(self): assert filter(lambda x: x != "a", "a small text") == " smll text" + +class AppTestXRange: + def test_xrange(self): + x = xrange(2, 9, 3) + assert x[1] == 5 + assert len(x) == 3 + assert list(x) == [2, 5, 8] + # test again, to make sure that xrange() is not its own iterator + assert list(x) == [2, 5, 8] From cfbolz at codespeak.net Tue Aug 9 18:26:07 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 18:26:07 +0200 (CEST) Subject: [pypy-svn] r15847 - pypy/dist/pypy/rpython/test Message-ID: <20050809162607.498DE27B48@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 18:26:06 2005 New Revision: 15847 Modified: pypy/dist/pypy/rpython/test/test_llinterp.py Log: oops. accidentally checked in test_llinterp version that always uses lltypesimulation Modified: pypy/dist/pypy/rpython/test/test_llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_llinterp.py (original) +++ pypy/dist/pypy/rpython/test/test_llinterp.py Tue Aug 9 18:26:06 2005 @@ -9,7 +9,6 @@ from pypy.rpython import rstr from pypy.annotation.model import lltype_to_annotation from pypy.rpython.rarithmetic import r_uint, ovfcheck -from pypy.rpython.memory import gclltype # switch on logging of interp to show more info on failing tests @@ -74,8 +73,7 @@ t, typer = gengraph(func, [annotation(x) for x in values], viewbefore, policy) - interp = LLInterpreter(t.flowgraphs, typer, gclltype, - gclltype.prepare_graphs) + interp = LLInterpreter(t.flowgraphs, typer) _tcache[key] = (t, interp) # keep the cache small _lastinterpreted.append(key) From arigo at codespeak.net Tue Aug 9 18:29:03 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 18:29:03 +0200 (CEST) Subject: [pypy-svn] r15848 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20050809162903.A86F527B48@code1.codespeak.net> Author: arigo Date: Tue Aug 9 18:29:00 2005 New Revision: 15848 Modified: pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/module/__builtin__/test/test_functional.py Log: reversed() with __len__() support at app-level, and tests. Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Tue Aug 9 18:29:00 2005 @@ -331,8 +331,26 @@ if hasattr(iterable, '__reversed__'): return iterable.__reversed__() seq = list(iterable) - def reversed_gen(local_iterable): - len_iterable = len(local_iterable) - for index in range(len_iterable-1, -1, -1): - yield local_iterable[index] - return reversed_gen(seq) + return reversed_iterator(seq) + + +class reversed_iterator(object): + + def __init__(self, seq): + self.seq = seq + self.remaining = len(seq) + + def __iter__(self): + return self + + def next(self): + i = self.remaining + if i > 0: + i -= 1 + item = self.seq[i] + self.remaining = i + return item + raise StopIteration + + def __len__(self): + return self.remaining Modified: pypy/dist/pypy/module/__builtin__/test/test_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_functional.py Tue Aug 9 18:29:00 2005 @@ -98,3 +98,19 @@ assert list(x) == [2, 5, 8] # test again, to make sure that xrange() is not its own iterator assert list(x) == [2, 5, 8] + +class AppTestReversed: + def test_reversed(self): + r = reversed("hello") + assert iter(r) is r + assert len(r) == 5 + assert r.next() == "o" + assert r.next() == "l" + assert r.next() == "l" + assert r.next() == "e" + assert len(r) == 1 + assert r.next() == "h" + assert len(r) == 0 + raises(StopIteration, r.next) + assert len(r) == 0 + assert list(reversed(reversed("hello"))) == ['h', 'e', 'l', 'l', 'o'] From pedronis at codespeak.net Tue Aug 9 18:31:45 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 9 Aug 2005 18:31:45 +0200 (CEST) Subject: [pypy-svn] r15849 - in pypy/dist/pypy/translator: . goal Message-ID: <20050809163145.70DE127B48@code1.codespeak.net> Author: pedronis Date: Tue Aug 9 18:31:43 2005 New Revision: 15849 Modified: pypy/dist/pypy/translator/ann_override.py pypy/dist/pypy/translator/goal/targetpypymain.py pypy/dist/pypy/translator/goal/targetpypystandalone.py pypy/dist/pypy/translator/goal/translate_pypy.py Log: let targets optionally specify a policy Modified: pypy/dist/pypy/translator/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/ann_override.py (original) +++ pypy/dist/pypy/translator/ann_override.py Tue Aug 9 18:31:43 2005 @@ -7,6 +7,7 @@ from pypy.annotation import specialize class PyPyAnnotatorPolicy(AnnotatorPolicy): + allow_someobjects = False def override__wrap_exception_cls(pol, space, x): import pypy.objspace.std.typeobject as typeobject Modified: pypy/dist/pypy/translator/goal/targetpypymain.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypymain.py Tue Aug 9 18:31:43 2005 @@ -7,6 +7,7 @@ from pypy.annotation.listdef import ListDef from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from pypy.translator.ann_override import PyPyAnnotatorPolicy # WARNING: this requires the annotator. # There is no easy way to build all caches manually, @@ -71,7 +72,7 @@ res = entry_point("app_basic_example.py") assert res == 0 - return entry_point, [SomeString()] + return entry_point, [SomeString()], PyPyAnnotatorPolicy() def get_llinterp_args(): from pypy.rpython import rstr Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Tue Aug 9 18:31:43 2005 @@ -7,6 +7,7 @@ from pypy.annotation.listdef import ListDef from pypy.interpreter import gateway from pypy.interpreter.error import OperationError +from pypy.translator.ann_override import PyPyAnnotatorPolicy # WARNING: this requires the annotator. # There is no easy way to build all caches manually, @@ -66,5 +67,5 @@ res = entry_point(["pypy", "app_basic_example.py"]) assert res == 0 - return entry_point, None + return entry_point, None, PyPyAnnotatorPolicy() Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Tue Aug 9 18:31:43 2005 @@ -71,11 +71,11 @@ import threading, pdb from pypy.translator.translator import Translator -from pypy.translator.ann_override import PyPyAnnotatorPolicy from pypy.annotation import model as annmodel from pypy.annotation import listdef from pypy.tool.cache import Cache from pypy.annotation.model import SomeObject +from pypy.annotation.policy import AnnotatorPolicy from pypy.tool.udir import udir from pypy.tool.ansi_print import ansi_print from pypy.translator.pickle.main import load, save @@ -97,25 +97,30 @@ def analyse(target): global t, entry_point, inputtypes, standalone + policy = AnnotatorPolicy() if target: - entry_point, inputtypes = target() + spec = target() + try: + entry_point, inputtypes, policy = spec + except ValueError: + entry_point, inputtypes = spec t = Translator(entry_point, verbose=True, simplifying=True) a = None else: # otherwise we have been loaded a = t.annotator t.frozen = False + standalone = inputtypes is None - policy = PyPyAnnotatorPolicy() if standalone: ldef = listdef.ListDef(None, annmodel.SomeString()) inputtypes = [annmodel.SomeList(ldef)] - policy.allow_someobjects = False if listen_port: run_async_server() if not options['-no-a']: print 'Annotating...' + print 'with policy: %s.%s' % (policy.__class__.__module__, policy.__class__.__name__) a = t.annotate(inputtypes, policy=policy) sanity_check_exceptblocks(t) lost = query.sanity_check_methods(t) From cfbolz at codespeak.net Tue Aug 9 18:35:09 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 18:35:09 +0200 (CEST) Subject: [pypy-svn] r15850 - pypy/dist/pypy/rpython/memory Message-ID: <20050809163509.05C8227B48@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 18:35:08 2005 New Revision: 15850 Modified: pypy/dist/pypy/rpython/memory/gclltype.py Log: cosmetics Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Tue Aug 9 18:35:08 2005 @@ -29,8 +29,8 @@ del notimplemented -def prepare_graphs(translator): +def prepare_graphs(flowgraphs): from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter - fgcc = FlowGraphConstantConverter(translator) + fgcc = FlowGraphConstantConverter(flowgraphs) fgcc.convert() From cfbolz at codespeak.net Tue Aug 9 18:42:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 9 Aug 2005 18:42:17 +0200 (CEST) Subject: [pypy-svn] r15851 - pypy/dist/pypy/rpython/memory Message-ID: <20050809164217.1F40D27B48@code1.codespeak.net> Author: cfbolz Date: Tue Aug 9 18:42:12 2005 New Revision: 15851 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: don't convert UnboundMethods. make function ptrs work. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Tue Aug 9 18:42:12 2005 @@ -12,6 +12,9 @@ import types, struct +FUNCTIONTYPES = (types.FunctionType, types.UnboundMethodType, + types.BuiltinFunctionType) + class LLTypeConverter(object): def __init__(self, address): self.converted = {} @@ -149,7 +152,7 @@ continue elif isinstance(cand, lltype.LowLevelType): continue - elif isinstance(cand, types.FunctionType): + elif isinstance(cand, FUNCTIONTYPES): continue elif isinstance(cand, str): continue @@ -194,7 +197,7 @@ self.constants[constant] = constant.value elif isinstance(constant.value, str): self.constants[constant] = constant.value - elif isinstance(constant.value, types.FunctionType): + elif isinstance(constant.value, FUNCTIONTYPES): self.constants[constant] = constant.value else: self.constants[constant] = self.cvter.convert(constant.value) Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Tue Aug 9 18:42:12 2005 @@ -98,6 +98,8 @@ return simulatorptr(T, address.address[0]) elif isinstance(T, lltype.PyObjectType): return simulatorptr(lltype.Ptr(T), address) + elif isinstance(T, lltype.FuncType): + return simulatorptr(lltype.Ptr(T), address) else: assert 0, "not implemented yet" From nik at codespeak.net Tue Aug 9 18:54:46 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 9 Aug 2005 18:54:46 +0200 (CEST) Subject: [pypy-svn] r15854 - pypy/dist/lib-python Message-ID: <20050809165446.CB0B827B4D@code1.codespeak.net> Author: nik Date: Tue Aug 9 18:54:45 2005 New Revision: 15854 Modified: pypy/dist/lib-python/failure_list.txt Log: looked into test_multibytecodec Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Tue Aug 9 18:54:45 2005 @@ -69,3 +69,7 @@ test_sys (FIXED) refcount test disabled (considered implementation detail from CPython) + +test_multibytecodec + needs the gb18030 codec, part of the CJK codecs. either remove this test + from core or maybe fake or reimplement the CJK codecs? From arigo at codespeak.net Tue Aug 9 19:01:52 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 19:01:52 +0200 (CEST) Subject: [pypy-svn] r15856 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050809170152.3631527B4D@code1.codespeak.net> Author: arigo Date: Tue Aug 9 19:01:47 2005 New Revision: 15856 Modified: pypy/dist/pypy/objspace/std/iterobject.py pypy/dist/pypy/objspace/std/listtype.py pypy/dist/pypy/objspace/std/test/test_iterobject.py pypy/dist/pypy/objspace/std/test/test_listobject.py Log: * some clean-ups of W_SeqIterObject, trying to minimize the number of fields required on the iterator instances. * more tests. * why did lst.__reversed__() store the iterator on the list object?? Note that space.unwrap() should not be used; instead use space.int_w(), or space.str_w(), etc. Modified: pypy/dist/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/iterobject.py (original) +++ pypy/dist/pypy/objspace/std/iterobject.py Tue Aug 9 19:01:47 2005 @@ -9,22 +9,15 @@ class W_SeqIterObject(W_Object): from pypy.objspace.std.itertype import iter_typedef as typedef + direction = +1 - def __init__(w_self, space, w_seq, index=0, reverse=False): + def __init__(w_self, space, w_seq, index=0): W_Object.__init__(w_self, space) w_self.w_seq = w_seq - try: - w_self.length = space.unwrap(space.len(w_seq)) - except OperationError,e: - if e.match(space, space.w_TypeError): - w_self.length = 0 - else: - raise w_self.index = index - if index < 0: - w_self.index += w_self.length - w_self.reverse = reverse - w_self.consumed = 0 + +class W_ReverseSeqIterObject(W_SeqIterObject): + direction = -1 registerimplementation(W_SeqIterObject) @@ -34,36 +27,24 @@ def next__SeqIter(space, w_seqiter): if w_seqiter.w_seq is None: - raise OperationError(space.w_StopIteration, space.w_None) + raise OperationError(space.w_StopIteration, space.w_None) try: - if w_seqiter.index >=0: - w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index)) - else: - raise OperationError(space.w_StopIteration, space.w_None) + w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index)) except OperationError, e: w_seqiter.w_seq = None if not e.match(space, space.w_IndexError): raise raise OperationError(space.w_StopIteration, space.w_None) - if w_seqiter.reverse: - w_seqiter.index -= 1 - else: - w_seqiter.index += 1 - w_seqiter.consumed += 1 + w_seqiter.index += w_seqiter.direction return w_item def len__SeqIter(space, w_seqiter): - if w_seqiter.w_seq is None : + if w_seqiter.w_seq is None: return space.wrap(0) - w_index = space.sub(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.index)) - if space.is_true(space.gt(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.index))): - if w_seqiter.reverse: - w_len = space.wrap(w_seqiter.index+1) - else: - w_len = space.sub(space.len(w_seqiter.w_seq), space.wrap(w_seqiter.consumed)) - else: - w_seqiter.w_seq = None - w_len = space.wrap(0) + index = w_seqiter.index + if w_seqiter.direction == -1: + index = ~index # -1=>0, -2=>1, etc. + w_len = space.sub(space.len(w_seqiter.w_seq), space.wrap(index)) return w_len register_all(vars()) Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Tue Aug 9 19:01:47 2005 @@ -1,6 +1,5 @@ from __future__ import generators from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.iterobject import W_SeqIterObject from pypy.objspace.std.register_all import register_all from sys import maxint @@ -26,9 +25,9 @@ ## ##''', filename=__file__).interphook('reversed') def list_reversed__ANY(space, w_list): - w_list.running_iter = W_SeqIterObject(space,w_list,-1,True) - return w_list.running_iter - + from pypy.objspace.std.iterobject import W_ReverseSeqIterObject + return W_ReverseSeqIterObject(space,w_list,-1) + register_all(vars(), globals()) # ____________________________________________________________ Modified: pypy/dist/pypy/objspace/std/test/test_iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_iterobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_iterobject.py Tue Aug 9 19:01:47 2005 @@ -120,34 +120,37 @@ raises(StopIteration, it.next) assert len(it) == 0 -## def test_iter_len_deque(self): -## from collections import deque -## -## iterable = deque((1,2,3,4)) -## it = iter(iterable) -## for i in reversed(range(len(it))): -## assert len(it) == i+1 -## x = it.next() -## print x -## raises(StopIteration, it.next) -## assert len(it) == 0 -## -## def test_iter_len_xrange(self): -## iterable = xrange(8) -## it = iter(iterable) -## for i in reversed(range(len(it))): -## assert len(it) == i+1 -## x = it.next() -## print x -## raises(StopIteration, it.next) -## assert len(it) == 0 -## -## def test_iter_len_reversed(self): -## iterable = reversed((1,2,3,4)) -## it = iter(iterable) -## for i in reversed(range(len(it))): -## assert len(it) == i+1 -## x = it.next() -## print x -## raises(StopIteration, it.next) -## assert len(it) == 0 + def test_iter_len_deque(self): + from collections import deque + + iterable = deque((1,2,3,4)) + it = iter(iterable) + for i in reversed(range(len(it))): + assert len(it) == i+1 + x = it.next() + print x + raises(StopIteration, it.next) + assert len(it) == 0 + + def test_iter_len_reversed(self): + iterable = reversed((1,2,3,4)) + it = iter(iterable) + for i in reversed(range(len(it))): + assert len(it) == i+1 + x = it.next() + print x + raises(StopIteration, it.next) + assert len(it) == 0 + + def test_len_reversed_seqiter(self): + it = reversed([5,6,7]) + assert iter(it) is it + assert len(it) == 3 + assert it.next() == 7 + assert len(it) == 2 + assert it.next() == 6 + assert len(it) == 1 + assert it.next() == 5 + assert len(it) == 0 + raises(StopIteration, it.next) + assert len(it) == 0 Modified: pypy/dist/pypy/objspace/std/test/test_listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_listobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_listobject.py Tue Aug 9 19:01:47 2005 @@ -558,3 +558,7 @@ c = list('hello world') c.reverse() assert ''.join(c) == 'dlrow olleh' + + def test_reversed(self): + assert list(list('hello').__reversed__()) == ['o', 'l', 'l', 'e', 'h'] + assert list(reversed(list('hello'))) == ['o', 'l', 'l', 'e', 'h'] From arigo at codespeak.net Tue Aug 9 19:22:00 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 19:22:00 +0200 (CEST) Subject: [pypy-svn] r15857 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20050809172200.26BF127B46@code1.codespeak.net> Author: arigo Date: Tue Aug 9 19:21:56 2005 New Revision: 15857 Modified: pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/module/__builtin__/test/test_functional.py Log: Oups, sorry: len(iter(xrange(..))) works indeed in Python 2.4. Re-implemented it as a separate xrange_iterator class. Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Tue Aug 9 19:21:56 2005 @@ -310,10 +310,28 @@ raise IndexError, "xrange object index out of range" def __iter__(self): - i = 0 - while i < self.len: - yield self.start + i * self.step - i += 1 + return xrange_iterator(self.start, self.len, self.step) + + +class xrange_iterator(object): + def __init__(self, current, remaining, step): + self._current = current + self._remaining = remaining + self._step = step + + def __iter__(self): + return self + + def next(self): + if self._remaining > 0: + item = self._current + self._current = item + self._step + self._remaining -= 1 + return item + raise StopIteration + + def __len__(self): + return self._remaining # ____________________________________________________________ Modified: pypy/dist/pypy/module/__builtin__/test/test_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_functional.py Tue Aug 9 19:21:56 2005 @@ -99,6 +99,22 @@ # test again, to make sure that xrange() is not its own iterator assert list(x) == [2, 5, 8] + def test_xrange_iter(self): + x = xrange(2, 9, 3) + it = iter(x) + assert iter(it) is it + assert len(it) == 3 + assert it.next() == 2 + assert len(it) == 2 + assert it.next() == 5 + assert len(it) == 1 + assert it.next() == 8 + assert len(it) == 0 + raises(StopIteration, it.next) + assert len(it) == 0 + # test again, to make sure that xrange() is not its own iterator + assert iter(x).next() == 2 + class AppTestReversed: def test_reversed(self): r = reversed("hello") From pedronis at codespeak.net Tue Aug 9 19:58:56 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 9 Aug 2005 19:58:56 +0200 (CEST) Subject: [pypy-svn] r15858 - pypy/dist/pypy/lib Message-ID: <20050809175856.4DD9F27B46@code1.codespeak.net> Author: pedronis Date: Tue Aug 9 19:58:55 2005 New Revision: 15858 Removed: pypy/dist/pypy/lib/collections.py Log: removing for reverting Deleted: /pypy/dist/pypy/lib/collections.py ============================================================================== --- /pypy/dist/pypy/lib/collections.py Tue Aug 9 19:58:55 2005 +++ (empty file) @@ -1,284 +0,0 @@ -"""High performance data structures -""" -# -# Copied and completed from the sandbox of CPython -# (nondist/sandbox/collections/pydeque.py rev 1.1, Raymond Hettinger) -# - -import operator -try: - from thread import get_ident as _thread_ident -except ImportError: - def _thread_ident(): - return -1 - - -n = 30 -LFTLNK = n -RGTLNK = n+1 -BLOCKSIZ = n+2 - -class deque(object): - - def __new__(cls, iterable=()): - self = super(deque, cls).__new__(cls) - self.clear() - return self - - def __init__(self, iterable=()): - add = self.append - for elem in iterable: - add(elem) - - def clear(self): - self.right = self.left = [None] * BLOCKSIZ - self.rightndx = n//2 # points to last written element - self.leftndx = n//2+1 - - def append(self, x): - self.rightndx += 1 - if self.rightndx == n: - newblock = [None] * BLOCKSIZ - self.right[RGTLNK] = newblock - newblock[LFTLNK] = self.right - self.right = newblock - self.rightndx = 0 - self.right[self.rightndx] = x - - def appendleft(self, x): - self.leftndx -= 1 - if self.leftndx == -1: - newblock = [None] * BLOCKSIZ - self.left[LFTLNK] = newblock - newblock[RGTLNK] = self.left - self.left = newblock - self.leftndx = n-1 - self.left[self.leftndx] = x - - def extend(self, iterable): - for elem in iterable: - self.append(elem) - - def extendleft(self, iterable): - for elem in iterable: - self.appendleft(elem) - - def pop(self): - if self.left is self.right and self.leftndx > self.rightndx: - raise IndexError, "pop from an empty deque" - x = self.right[self.rightndx] - self.right[self.rightndx] = None - self.rightndx -= 1 - if self.rightndx == -1: - prevblock = self.right[LFTLNK] - if prevblock is None: - # the deque has become empty; recenter instead of freeing block - self.rightndx = n//2 - self.leftndx = n//2+1 - else: - prevblock[RGTLNK] = None - self.right[LFTLNK] = None - self.right = prevblock - self.rightndx = n-1 - return x - - def popleft(self): - if self.left is self.right and self.leftndx > self.rightndx: - raise IndexError, "pop from an empty deque" - x = self.left[self.leftndx] - self.left[self.leftndx] = None - self.leftndx += 1 - if self.leftndx == n: - prevblock = self.left[RGTLNK] - if prevblock is None: - # the deque has become empty; recenter instead of freeing block - self.rightndx = n//2 - self.leftndx = n//2+1 - else: - prevblock[LFTLNK] = None - self.left[RGTLNK] = None - self.left = prevblock - self.leftndx = 0 - return x - - def remove(self, value): - del self[operator.indexOf(self, value)] - - def rotate(self, n=1): - length = len(self) - if length == 0: - return - halflen = (length+1) >> 1 - if n > halflen or n < -halflen: - n %= length - if n > halflen: - n -= length - elif n < -halflen: - n += length - while n > 0: - self.appendleft(self.pop()) - n -= 1 - while n < 0: - self.append(self.popleft()) - n += 1 - - def __repr__(self): - threadlocalattr = '__repr' + str(_thread_ident()) - if threadlocalattr in self.__dict__: - return 'deque([...])' - else: - self.__dict__[threadlocalattr] = True - try: - return 'deque(%r)' % (list(self),) - finally: - del self.__dict__[threadlocalattr] - - def __iter__(self): - return dequeIterator(self) - - - def __reversed__(self): - return dequeIterator(self,True) - - def __len__(self): - sum = 0 - block = self.left - while block: - sum += n - block = block[RGTLNK] - return sum + self.rightndx - self.leftndx + 1 - n - - def __getref(self, index): - if index >= 0: - block = self.left - while block: - l, r = 0, n - if block is self.left: - l = self.leftndx - if block is self.right: - r = self.rightndx + 1 - span = r-l - if index < span: - return block, l+index - index -= span - block = block[RGTLNK] - else: - block = self.right - while block: - l, r = 0, n - if block is self.left: - l = self.leftndx - if block is self.right: - r = self.rightndx + 1 - negative_span = l-r - if index >= negative_span: - return block, r+index - index -= negative_span - block = block[LFTLNK] - raise IndexError("deque index out of range") - - def __getitem__(self, index): - block, index = self.__getref(index) - return block[index] - - def __setitem__(self, index, value): - block, index = self.__getref(index) - block[index] = value - - def __delitem__(self, index): - length = len(self) - if index >= 0: - if index >= length: - raise IndexError("deque index out of range") - self.rotate(-index) - self.popleft() - self.rotate(index) - else: - index = ~index - if index >= length: - raise IndexError("deque index out of range") - self.rotate(index) - self.pop() - self.rotate(-index) - - def __reduce_ex__(self, proto): - return type(self), (), self.__dict__, iter(self), None - - def __hash__(self): - raise TypeError, "deque objects are unhashable" - - def __copy__(self): - return self.__class__(self) - - # XXX make comparison more efficient - def __eq__(self, other): - if isinstance(other, deque): - return list(self) == list(other) - else: - return NotImplemented - - def __ne__(self, other): - if isinstance(other, deque): - return list(self) != list(other) - else: - return NotImplemented - - def __lt__(self, other): - if isinstance(other, deque): - return list(self) < list(other) - else: - return NotImplemented - - def __le__(self, other): - if isinstance(other, deque): - return list(self) <= list(other) - else: - return NotImplemented - - def __gt__(self, other): - if isinstance(other, deque): - return list(self) > list(other) - else: - return NotImplemented - - def __ge__(self, other): - if isinstance(other, deque): - return list(self) >= list(other) - else: - return NotImplemented - -class dequeIterator: - - def __init__(self, dequeobj, reverse=False): - self.deque = dequeobj - self.length = len(dequeobj) - self.consumed = 0 - if reverse: - self.index = self.length-1 - self.inc = -1 - else: - self.index = 0 - self.inc = 1 - self.reverse = reverse - - def __iter__(self): - return self - - def next(self): - if self.length == len(self.deque): - if self.index < self.length and self.index >= 0: - res = self.deque[self.index] - self.index += self.inc - self.consumed += 1 - return res - else: - raise StopIteration - else: - self.deque = [] - self.index = 0 - self.length = self.consumed = 0 - raise RuntimeError("deque mutated during iteration") - - def __len__(self): - return self.length - self.consumed - \ No newline at end of file From pedronis at codespeak.net Tue Aug 9 20:00:25 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 9 Aug 2005 20:00:25 +0200 (CEST) Subject: [pypy-svn] r15859 - in pypy/dist/pypy/lib: . test2 Message-ID: <20050809180025.E266627B46@code1.codespeak.net> Author: pedronis Date: Tue Aug 9 20:00:23 2005 New Revision: 15859 Added: pypy/dist/pypy/lib/collections.py - copied, changed from r15144, pypy/dist/pypy/lib/collections.py Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py Log: keep using the algorithm, use generators for readability with a wrapper to support __len__ Copied: pypy/dist/pypy/lib/collections.py (from r15144, pypy/dist/pypy/lib/collections.py) ============================================================================== --- pypy/dist/pypy/lib/collections.py (original) +++ pypy/dist/pypy/lib/collections.py Tue Aug 9 20:00:23 2005 @@ -34,8 +34,11 @@ self.right = self.left = [None] * BLOCKSIZ self.rightndx = n//2 # points to last written element self.leftndx = n//2+1 + self.length = 0 + self.state = 0 def append(self, x): + self.state += 1 self.rightndx += 1 if self.rightndx == n: newblock = [None] * BLOCKSIZ @@ -43,9 +46,11 @@ newblock[LFTLNK] = self.right self.right = newblock self.rightndx = 0 + self.length += 1 self.right[self.rightndx] = x def appendleft(self, x): + self.state += 1 self.leftndx -= 1 if self.leftndx == -1: newblock = [None] * BLOCKSIZ @@ -53,6 +58,7 @@ newblock[RGTLNK] = self.left self.left = newblock self.leftndx = n-1 + self.length += 1 self.left[self.leftndx] = x def extend(self, iterable): @@ -68,7 +74,9 @@ raise IndexError, "pop from an empty deque" x = self.right[self.rightndx] self.right[self.rightndx] = None + self.length -= 1 self.rightndx -= 1 + self.state += 1 if self.rightndx == -1: prevblock = self.right[LFTLNK] if prevblock is None: @@ -87,7 +95,9 @@ raise IndexError, "pop from an empty deque" x = self.left[self.leftndx] self.left[self.leftndx] = None + self.length -= 1 self.leftndx += 1 + self.state += 1 if self.leftndx == n: prevblock = self.left[RGTLNK] if prevblock is None: @@ -134,6 +144,11 @@ del self.__dict__[threadlocalattr] def __iter__(self): + return deque_iterator(self, self._iter_impl) + + def _iter_impl(self, original_state, giveup): + if self.state != original_state: + giveup() block = self.left while block: l, r = 0, n @@ -143,9 +158,16 @@ r = self.rightndx + 1 for elem in block[l:r]: yield elem + if self.state != original_state: + giveup() block = block[RGTLNK] def __reversed__(self): + return deque_iterator(self, self._reversed_impl) + + def _reversed_impl(self, original_state, giveup): + if self.state != original_state: + giveup() block = self.right while block: l, r = 0, n @@ -155,15 +177,18 @@ r = self.rightndx + 1 for elem in reversed(block[l:r]): yield elem + if self.state != original_state: + giveup() block = block[LFTLNK] def __len__(self): - sum = 0 - block = self.left - while block: - sum += n - block = block[RGTLNK] - return sum + self.rightndx - self.leftndx + 1 - n + #sum = 0 + #block = self.left + #while block: + # sum += n + # block = block[RGTLNK] + #return sum + self.rightndx - self.leftndx + 1 - n + return self.length def __getref(self, index): if index >= 0: @@ -264,3 +289,23 @@ else: return NotImplemented +class deque_iterator(object): + + def __init__(self, deq, itergen): + self.counter = len(deq) + def giveup(): + self.counter = 0 + raise RuntimeError, "deque mutated during iteration" + self._gen = itergen(deq.state, giveup) + + def next(self): + res = self._gen.next() + self.counter -= 1 + return res + + def __iter__(self): + return self + + def __len__(self): + return self.counter + Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_deque_extra.py (original) +++ pypy/dist/pypy/lib/test2/test_deque_extra.py Tue Aug 9 20:00:23 2005 @@ -21,6 +21,7 @@ assert i == self.d[i] for i in range(n-1, -1, -1): assert self.d.pop() == i + assert len(self.d) == 0 def test_deque_iter(self): it = iter(self.d) @@ -37,7 +38,11 @@ assert len(it) == n assert it.next() == n-1 assert len(it) == n-1 + assert it.next() == n-2 + assert len(it) == n-2 self.d.pop() raises(RuntimeError,it.next) assert len(it) == 0 assert list(it) == [] + + From arigo at codespeak.net Tue Aug 9 21:26:31 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 21:26:31 +0200 (CEST) Subject: [pypy-svn] r15860 - pypy/dist/pypy/rpython/test Message-ID: <20050809192631.9085327B42@code1.codespeak.net> Author: arigo Date: Tue Aug 9 21:26:29 2005 New Revision: 15860 Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: Test case for a bug shown by translate_pypy. Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Tue Aug 9 21:26:29 2005 @@ -228,3 +228,22 @@ return s1 + s2 res = interpret(f, []) assert ''.join(list(res.chars)) == 'abc, def123' + +def INPROGRESS_test_method_repr(): + def g(n): + if n >= 0: + return "egg" + else: + return "spam" + def f(n): + # this is designed for a specific bug: conversions between + # BuiltinMethodRepr. The append method of the list is passed + # around, and g(-1) below causes a reflowing at the beginning + # of the loop (but not inside the loop). This situation creates + # a newlist returning a SomeList() which '==' but 'is not' the + # SomeList() inside the loop. + x = len([ord(c) for c in g(1)]) + g(-1) + return x + res = interpret(f, [0]) + assert res == 3 From arigo at codespeak.net Tue Aug 9 21:29:55 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 21:29:55 +0200 (CEST) Subject: [pypy-svn] r15861 - pypy/dist/pypy/rpython/test Message-ID: <20050809192955.A5A6F27B42@code1.codespeak.net> Author: arigo Date: Tue Aug 9 21:29:53 2005 New Revision: 15861 Modified: pypy/dist/pypy/rpython/test/test_rstr.py Log: A test (failing for now) about converting string-or-none to PyStringObject. Fixing it would require putting PyString_FromLLCharArrayAndSize in the extfunc table, but I'm not exactly sure how to express functions working with a mixture of low-level and high-level types. Modified: pypy/dist/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rstr.py (original) +++ pypy/dist/pypy/rpython/test/test_rstr.py Tue Aug 9 21:29:53 2005 @@ -431,3 +431,20 @@ assert ''.join(res.chars) == 'a'*4 res = interpret(f, ['a', 0]) assert ''.join(res.chars) == "" + +def FIXME_test_str_to_pystringobj(): + def f(n): + if n >= 0: + return "hello"[n:] + else: + return None + def g(n): + if n == -2: + return 42 + return f(n) + res = interpret(g, [-1]) + assert res._obj.value == None + res = interpret(g, [1]) + assert res._obj.value == "ello" + res = interpret(g, [-2]) + assert res._obj.value == 42 From arigo at codespeak.net Tue Aug 9 21:50:49 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 21:50:49 +0200 (CEST) Subject: [pypy-svn] r15862 - in pypy/dist/pypy/rpython: . test Message-ID: <20050809195049.BFF3D27B42@code1.codespeak.net> Author: arigo Date: Tue Aug 9 21:50:46 2005 New Revision: 15862 Modified: pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/test/test_rbuiltin.py Log: Convert between BuiltinMethodReprs by converting their 'self' argument accordingly (as long as they are the same method name). Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Tue Aug 9 21:50:46 2005 @@ -88,13 +88,14 @@ hop2.args_r[0] = self.self_repr return bltintyper(hop2) - -##class __extend__(pairtype(SomeBuiltin, SomeObject)): - -## def rtype_convert_from_to((s_blt, s_to), v, llops): -## if s_blt.s_self is None: -## raise TyperError("conversion requested on a built-in function") -## return llops.convertvar(v, s_blt.s_self, s_to) +class __extend__(pairtype(BuiltinMethodRepr, BuiltinMethodRepr)): + def convert_from_to((r_from, r_to), v, llops): + # convert between two MethodReprs only if they are about the same + # methodname. (Useful for the case r_from.s_self == r_to.s_self but + # r_from is not r_to.) See test_rbuiltin.test_method_repr. + if r_from.methodname != r_to.methodname: + return NotImplemented + return llops.convertvar(v, r_from.self_repr, r_to.self_repr) # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/test/test_rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbuiltin.py (original) +++ pypy/dist/pypy/rpython/test/test_rbuiltin.py Tue Aug 9 21:50:46 2005 @@ -229,7 +229,7 @@ res = interpret(f, []) assert ''.join(list(res.chars)) == 'abc, def123' -def INPROGRESS_test_method_repr(): +def test_method_repr(): def g(n): if n >= 0: return "egg" From pedronis at codespeak.net Tue Aug 9 22:39:34 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 9 Aug 2005 22:39:34 +0200 (CEST) Subject: [pypy-svn] r15864 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050809203934.3D31227B42@code1.codespeak.net> Author: pedronis Date: Tue Aug 9 22:39:33 2005 New Revision: 15864 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_deque.py Log: oops, forgot to checkin, cut some constants Modified: pypy/dist/lib-python/modified-2.4.1/test/test_deque.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_deque.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_deque.py Tue Aug 9 22:39:33 2005 @@ -101,7 +101,7 @@ self.assertEqual(list(d), l) def test_delitem(self): - n = 500 # O(n**2) test, don't make this too big + n = 10 # O(n**2) test, don't make this too big d = deque(xrange(n)) self.assertRaises(IndexError, d.__delitem__, -n-1) self.assertRaises(IndexError, d.__delitem__, n) @@ -330,7 +330,7 @@ self.assertEqual(list(d), list(e)) def test_reversed(self): - for s in ('abcd', xrange(2000)): + for s in ('abcd', xrange(200)): self.assertEqual(list(reversed(deque(s))), list(reversed(s))) def test_gc_doesnt_blowup(self): From arigo at codespeak.net Tue Aug 9 23:08:49 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 9 Aug 2005 23:08:49 +0200 (CEST) Subject: [pypy-svn] r15869 - in pypy/dist/pypy: objspace/flow translator Message-ID: <20050809210849.8057227B3F@code1.codespeak.net> Author: arigo Date: Tue Aug 9 23:08:45 2005 New Revision: 15869 Modified: pypy/dist/pypy/objspace/flow/objspace.py pypy/dist/pypy/translator/geninterplevel.py Log: FloatingPointError is never raised by CPython unless you compile it specially. So for now it makes sense to forget about it as well. Disabled it as an implicit exception in the flow graphs... Modified: pypy/dist/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/objspace.py (original) +++ pypy/dist/pypy/objspace/flow/objspace.py Tue Aug 9 23:08:45 2005 @@ -429,7 +429,7 @@ ('typ', TypeError), ('zer', ZeroDivisionError), ('val', ValueError), - ('flo', FloatingPointError) + #('flo', FloatingPointError) ): op_appendices[_exc] = _name del _name, _exc @@ -466,10 +466,10 @@ 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("""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 Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Tue Aug 9 23:08:45 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.9' # bump this for substantial changes +GI_VERSION = '1.1.10' # bump this for substantial changes # ____________________________________________________________ try: From ericvrp at codespeak.net Tue Aug 9 23:51:57 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 9 Aug 2005 23:51:57 +0200 (CEST) Subject: [pypy-svn] r15870 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050809215157.6B80B27B3F@code1.codespeak.net> Author: ericvrp Date: Tue Aug 9 23:51:55 2005 New Revision: 15870 Modified: pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: fixed (u)int_invert Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Tue Aug 9 23:51:55 2005 @@ -153,13 +153,19 @@ self.db.repr_arg(op.args[0]), "true") - def int_invert(self, op): #XXX do we have a test for this, it doesn't look right? + def int_invert(self, op): self.codewriter.binaryop("xor", self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), - 1) - uint_invert = int_invert + -1) + + def uint_invert(self, op): + self.codewriter.binaryop("xor", + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + self.db.repr_arg(op.args[0]), + str((1<<32)-1)) def binaryop(self, op): name = self.binary_operations[op.opname] Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Tue Aug 9 23:51:55 2005 @@ -323,3 +323,19 @@ for value in range(15): i = r_uint(value) assert f(i) == fn(i) + +def test_int_invert(): + def fn(i): + return ~i + f = compile_function(fn, [int]) + for i in range(-15,15): + assert f(i) == fn(i) + +def test_uint_invert(): + py.test.skip("not sure why uint annotated function can return -1 (pyrex?)") + def fn(i): + return ~i + f = compile_function(fn, [r_uint]) + for value in range(15): + i = r_uint(value) + assert str(f(i)) == str(fn(i)) From ericvrp at codespeak.net Tue Aug 9 23:52:41 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 9 Aug 2005 23:52:41 +0200 (CEST) Subject: [pypy-svn] r15871 - in pypy/dist/pypy/translator/llvm2: . demo Message-ID: <20050809215241.4605B27B41@code1.codespeak.net> Author: ericvrp Date: Tue Aug 9 23:52:40 2005 New Revision: 15871 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/demo/run.py pypy/dist/pypy/translator/llvm2/genllvm.py Log: fixed ability to generate standalone executables Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Tue Aug 9 23:52:40 2005 @@ -155,14 +155,17 @@ log.build(cmd) cmdexec(cmd) -def make_module_from_llvm(llvmfile, pyxfile, optimize=True, exe_name=None): +def make_module_from_llvm(llvmfile, pyxfile=None, optimize=True, exe_name=None): include_dir = py.magic.autopath().dirpath() dirpath = llvmfile.dirpath() lastdir = path.local() os.chdir(str(dirpath)) - modname = pyxfile.purebasename b = llvmfile.purebasename - source_files = [ "%s.c" % modname ] + if pyxfile: + modname = pyxfile.purebasename + source_files = [ "%s.c" % modname ] + else: + source_files = [] object_files = [] library_files = [] if use_boehm_gc: @@ -195,7 +198,8 @@ source_files.append("%s.c" % b) try: - log.build("modname", modname) + if pyxfile: + log.build("modname", modname) c = stdoutcapture.Capture(mixed_out_err = True) log.build("working in", path.local()) try: @@ -203,25 +207,30 @@ for cmd in cmds: log.build(cmd) cmdexec(cmd) - make_c_from_pyxfile(pyxfile) - compile_module(modname, source_files, object_files, library_files) + if pyxfile: + make_c_from_pyxfile(pyxfile) + compile_module(modname, source_files, object_files, library_files) finally: foutput, foutput = c.done() except: data = foutput.read() - fdump = open("%s.errors" % modname, "w") - fdump.write(data) - fdump.close() + if pyxfile: + fdump = open("%s.errors" % modname, "w") + fdump.write(data) + fdump.close() log.build(data) raise # XXX do we need to do some check on fout/ferr? # XXX not a nice way to import a module - log.build("inserting path to sys.path", dirpath) - sys.path.insert(0, '.') - cmd = "import %(modname)s as testmodule" % locals() - log.build(cmd) - exec cmd - sys.path.pop(0) + if pyxfile: + log.build("inserting path to sys.path", dirpath) + sys.path.insert(0, '.') + cmd = "import %(modname)s as testmodule" % locals() + log.build(cmd) + exec cmd + sys.path.pop(0) finally: os.chdir(str(lastdir)) - return testmodule + if pyxfile: + return testmodule + return None Modified: pypy/dist/pypy/translator/llvm2/demo/run.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/run.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/run.py Tue Aug 9 23:52:40 2005 @@ -2,7 +2,7 @@ import os import sys -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm2.genllvm import compile_module from pypy.translator.translator import Translator def p(): @@ -18,7 +18,7 @@ f() def l(name): - compile_function(entry_point, [], exe_name=name) + compile_module(entry_point, [], standalone=True, exe_name=name) print 'Running standalone (llvm-based) executable:' cmd = "/tmp/usession-current/%s" % name print cmd Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Tue Aug 9 23:52:40 2005 @@ -39,7 +39,7 @@ self.debug = debug def gen_llvm_source(self, func=None): - print 'gen_llvm_source begin) ' + time.ctime() + if self.debug: print 'gen_llvm_source begin) ' + time.ctime() if func is None: func = self.translator.entrypoint self.entrypoint = func @@ -57,11 +57,11 @@ self.db.prepare_repr_arg(c) assert c in self.db.obj2node - print 'gen_llvm_source db.setup_all) ' + time.ctime() + if self.debug: print 'gen_llvm_source db.setup_all) ' + time.ctime() #7 minutes self.db.setup_all() - print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() - print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) + if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() + if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) #3 seconds if self.debug: log.gen_llvm_source(self.db.dump_pbcs()) @@ -85,34 +85,34 @@ for typ_decl in self.db.getnodes(): typ_decl.writedatatypedecl(codewriter) - print 'gen_llvm_source typ_decl.writeglobalconstants) ' + time.ctime() + if self.debug: print 'gen_llvm_source typ_decl.writeglobalconstants) ' + time.ctime() #20 minutes nl(); comment("Global Data") ; nl() for typ_decl in self.db.getnodes(): typ_decl.writeglobalconstants(codewriter) - print 'gen_llvm_source typ_decl.writecomments) ' + time.ctime() + if self.debug: print 'gen_llvm_source typ_decl.writecomments) ' + time.ctime() #0 minutes if self.debug: nl(); comment("Comments") ; nl() for typ_decl in self.db.getnodes(): typ_decl.writecomments(codewriter) - print 'gen_llvm_source extdeclarations) ' + time.ctime() + if self.debug: print 'gen_llvm_source extdeclarations) ' + time.ctime() nl(); comment("Function Prototypes") ; nl() if self.embedexterns: for extdecl in extdeclarations.split('\n'): codewriter.append(extdecl) - print 'gen_llvm_source self._debug_prototype) ' + time.ctime() + if self.debug: print 'gen_llvm_source self._debug_prototype) ' + time.ctime() if self.debug: self._debug_prototype(codewriter) - print 'gen_llvm_source typ_decl.writedecl) ' + time.ctime() + if self.debug: print 'gen_llvm_source typ_decl.writedecl) ' + time.ctime() for typ_decl in self.db.getnodes(): typ_decl.writedecl(codewriter) - print 'gen_llvm_source boehm_gc) ' + time.ctime() + if self.debug: print 'gen_llvm_source boehm_gc) ' + time.ctime() nl(); comment("Function Implementation") codewriter.startimpl() if use_boehm_gc: @@ -122,12 +122,12 @@ for gc_func in gc_funcs.split('\n'): codewriter.append(gc_func) - print 'gen_llvm_source typ_decl.writeimpl) ' + time.ctime() + if self.debug: print 'gen_llvm_source typ_decl.writeimpl) ' + time.ctime() #XXX ? minutes for typ_decl in self.db.getnodes(): typ_decl.writeimpl(codewriter) - print 'gen_llvm_source used_external_functions) ' + time.ctime() + if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() depdone = {} for funcname,value in ExternalFuncNode.used_external_functions.iteritems(): deps = dependencies(funcname,[]) @@ -145,7 +145,7 @@ codewriter.append(extfunc) depdone[dep] = True - print 'gen_llvm_source entrypoint) ' + time.ctime() + if self.debug: print 'gen_llvm_source entrypoint) ' + time.ctime() #XXX use codewriter methods here decl = self.entrynode.getdecl() t = decl.split('%', 1) @@ -175,27 +175,29 @@ codewriter.newline() comment("End of file") ; nl() - print 'gen_llvm_source return) ' + time.ctime() + if self.debug: print 'gen_llvm_source return) ' + time.ctime() return filename - def create_module(self, filename, exe_name=None): + def create_module(self, filename, really_compile=True, standalone=False, optimize=True, exe_name=None): if not llvm_is_on_path(): py.test.skip("llvm not found") # XXX not good to call py.test.skip here - postfix = '' - pyxsource = filename.new(basename=filename.purebasename+'_wrapper'+postfix+'.pyx') - write_pyx_wrapper(self.entrynode, pyxsource) - - return build_llvm_module.make_module_from_llvm(filename, pyxsource, exe_name=exe_name) + if standalone: + return build_llvm_module.make_module_from_llvm(filename, optimize=optimize, exe_name=exe_name) + else: + postfix = '' + pyxfile = filename.new(basename=filename.purebasename+'_wrapper'+postfix+'.pyx') + write_pyx_wrapper(self.entrynode, pyxfile) + return build_llvm_module.make_module_from_llvm(filename, pyxfile=pyxfile, optimize=optimize) def _debug_prototype(self, codewriter): codewriter.append("declare int %printf(sbyte*, ...)") -def genllvm(translator, embedexterns=True, exe_name=None): +def genllvm(translator, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): gen = GenLLVM(translator, embedexterns=embedexterns) filename = gen.gen_llvm_source() #log.genllvm(open(filename).read()) - return gen.create_module(filename, exe_name) + return gen.create_module(filename, really_compile=really_compile, standalone=standalone, optimize=optimize, exe_name=exe_name) def llvm_is_on_path(): try: @@ -204,19 +206,19 @@ return False return True -def compile_module(function, annotation, view=False, embedexterns=True, exe_name=None): +def compile_module(function, annotation, view=False, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): t = Translator(function) a = t.annotate(annotation) t.specialize() if view: t.view() - return genllvm(t, embedexterns=embedexterns, exe_name=exe_name) + return genllvm(t, really_compile=really_compile, standalone=standalone, optimize=optimize, embedexterns=embedexterns, exe_name=exe_name) -def compile_function(function, annotation, view=False, embedexterns=True, exe_name=None): - mod = compile_module(function, annotation, view, embedexterns=embedexterns, exe_name=exe_name) +def compile_function(function, annotation, view=False, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): + mod = compile_module(function, annotation, view=view, really_compile=really_compile, standalone=standalone, optimize=optimize, embedexterns=embedexterns, exe_name=exe_name) return getattr(mod, function.func_name + "_wrapper") -def compile_module_function(function, annotation, view=False, embedexterns=True, exe_name=None): - mod = compile_module(function, annotation, view, embedexterns=embedexterns, exe_name=exe_name) +def compile_module_function(function, annotation, view=False, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): + mod = compile_module(function, annotation, view=view, really_compile=really_compile, standalone=standalone, optimize=optimize, embedexterns=embedexterns, exe_name=exe_name) f = getattr(mod, function.func_name + "_wrapper") return mod, f From tismer at codespeak.net Tue Aug 9 23:55:45 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 9 Aug 2005 23:55:45 +0200 (CEST) Subject: [pypy-svn] r15872 - pypy/dist/pypy/objspace/std Message-ID: <20050809215545.39BEB27B3F@code1.codespeak.net> Author: tismer Date: Tue Aug 9 23:55:42 2005 New Revision: 15872 Modified: pypy/dist/pypy/objspace/std/strutil.py Log: a new version of string_to_float that produces correct results. Unfortunately, this now relieson the existence of long objects, so it has to be rewritten in interp level. Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Tue Aug 9 23:55:42 2005 @@ -4,6 +4,8 @@ from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_float_to_int, parts_to_float +import math + # XXX factor more functions out of stringobject.py. # This module is independent from PyPy. @@ -190,70 +192,52 @@ def string_to_float(s): + """ + Conversion of string to float. + This version tries to only raise on invalid literals. + Overflows should be converted to infinity whenever possible. + """ + s = strip_spaces(s) if not s: raise ParseStringError("empty string for float()") + # 1) parse the string into pieces. sign, before_point, after_point, exponent = break_up_float(s) if not before_point and not after_point: raise ParseStringError("invalid string literal for float()") - r = 0.0 - i = len(before_point) - 1 - j = 0 - while i >= 0: - d = float(ord(before_point[i]) - ord('0')) - r += d * (10.0 ** j) - i -= 1 - j += 1 - - i = 0 - while i < len(after_point): - d = float(ord(after_point[i]) - ord('0')) - r += d * (10.0 ** (-i-1)) - i += 1 - - if exponent: - # XXX this fails for float('0.' + '0'*100 + '1e400') - # XXX later! - try: - e = string_to_int(exponent) - except ParseStringOverflowError: - if exponent[0] == '-': - e = -400 - else: - e = 400 - if e > 0: - if e >= 400: - r = 1e200 * 1e200 - else: - while e > 0: - r *= 10.0 - e -= 1 - else: - if e <= -400: - r = 0.0 - else: - while e < 0: - r /= 10.0 - e += 1 - - if sign == '-': - r = -r - - return r + try: + return parts_to_float(sign, before_point, after_point, exponent) + except ValueError: + raise ParseStringError("invalid string literal for float()") -# old version temporarily left here for comparison -old_string_to_float = string_to_float +# Tim's comment: # 57 bits are more than needed in any case. # to allow for some rounding, we take one # digit more. -MANTISSA_DIGITS = len(str( (1L << 57)-1 )) + 1 -def string_to_float(s): +# In the PyPy case, we can compute everything at compile time: +# XXX move this stuff to some central place, it is now also +# in _float_formatting. + +def calc_mantissa_bits(): + bits = 1 # I know it is almost always 53, but let it compute... + while 1: + pattern = (1L << bits) - 1 + comp = long(float(pattern)) + if comp != pattern: + return bits - 1 + bits += 1 + +MANTISSA_BITS = calc_mantissa_bits() +del calc_mantissa_bits +MANTISSA_DIGITS = len(str( (1L << MANTISSA_BITS)-1 )) + 1 + +def applevel_string_to_float(s): """ Conversion of string to float. This version tries to only raise on invalid literals. @@ -278,37 +262,28 @@ # in order to compensate between very long digit strings # and extreme exponent numbers, we try to avoid overflows # by adjusting the exponent by the number of mantissa - # digits. Exponent computation is done in integer, unless - # we get an overflow, where we fall back to float. - # Usage of long numbers is explicitly avoided, because - # we want to be able to work without longs as a PyPy option. - - # Observations: - # because we are working on a 10-basis, which leads to - # precision loss when multiplying by a power of 10, we need to be - # careful about order of operation: - # additions must be made starting with the lowest digits - # powers of 10.0 should be calculated using **, because this is - # more exact than multiplication. - # avoid division/multiplication as much as possible. + # digits. For simplicity, all computations are done in + # long math. # The plan: # 1) parse the string into pieces. # 2) pre-calculate digit exponent dexp. # 3) truncate and adjust dexp. - # 4) compute the exponent. - # add the number of digits before the point to the exponent. - # if we get an overflow here, we try to compute the exponent - # by intermediate floats. - # 5) check the exponent for overflow and truncate to +-400. - # 6) add/multiply the digits in, adjusting e. + # 4) compute the exponent and truncate to +-400. + # 5) compute the value using long math and proper rounding. + # Positive results: + # The algorithm appears appears to produce correct round-trip + # values for the perfect input of _float_formatting. + # Note: + # XXX: the builtin rounding of long->float does not work, correctly. + # Ask Tim Peters for the reasons why no correct rounding is done. # XXX: limitations: - # the algorithm is probably not optimum concerning the resulting - # bit pattern, but very close to it. pre-computing to binary - # numbers would give less rounding in the last digit. But this is - # quite hard to do without longs. - + # - It is possibly not too efficient. + # - Really optimum results need a more sophisticated algorithm + # like Bellerophon from William D. Clinger, cf. + # http://citeseer.csail.mit.edu/clinger90how.html + s = strip_spaces(s) if not s: @@ -335,69 +310,54 @@ while p >= 0 and digits[p] == '0': p -= 1 dexp -= p + 1 + digits = digits[:p+1] + if len(digits) == 0: + digits = '0' - # 4) compute the exponent. + # 4) compute the exponent and truncate to +-400 if not exponent: exponent = '0' - try: - e = string_to_int(exponent) - e = ovfcheck(e + dexp) - except (ParseStringOverflowError, OverflowError): - fe = string_to_float(exponent) + dexp - try: - e = ovfcheck_float_to_int(fe) - except OverflowError: - # 4) check the exponent for overflow and truncate to +-400. - if exponent[0] == '-': - e = -400 - else: - e = 400 - # 5) check the exponent for overflow and truncate to +-400. + e = long(exponent) + dexp if e >= 400: e = 400 elif e <= -400: e = -400 - # e is now in a range that does not overflow on additions. - # 6) add/multiply the digits in, adjusting e. - r = 0.0 + # 5) compute the value using long math and proper rounding. + lr = long(digits) + if e >= 0: + bits = 0 + m = lr * 10L ** e + else: + # compute a sufficiently large scale + prec = MANTISSA_DIGITS * 2 + 22 # 128, maybe + bits = - (int(math.ceil(-e / math.log10(2) - 1e-10)) + prec) + scale = 2L ** -bits + pten = 10L ** -e + m = (lr * scale) // pten + + # we now have a fairly large mantissa. + # Shift it and round the last bit. + + # first estimate the bits and do a big shift + if m: + mbits = int(math.ceil(math.log(m, 2) - 1e-10)) + needed = MANTISSA_BITS + if mbits > needed: + if mbits > needed+1: + shifted = mbits - (needed+1) + m >>= shifted + bits += shifted + # do the rounding + bits += 1 + m = (m >> 1) + (m & 1) + try: - while p >= 0: - # note: exponentiation is intentionally used for - # exactness. If speed is an issue, this can easily - # be kept in a cache for every digit value. - r += (ord(digits[p]) - ord('0')) * 10.0 ** e - p -= 1 - e += 1 + r = math.ldexp(m, bits) except OverflowError: - r = 1e200 * 1e200 + r = 1e200 * 1e200 # produce inf, hopefully if sign == '-': r = -r return r - -disabled_string_to_float = string_to_float # not accurate enough - -def string_to_float(s): - """ - Conversion of string to float. - This version tries to only raise on invalid literals. - Overflows should be converted to infinity whenever possible. - """ - - s = strip_spaces(s) - - if not s: - raise ParseStringError("empty string for float()") - - # 1) parse the string into pieces. - sign, before_point, after_point, exponent = break_up_float(s) - - if not before_point and not after_point: - raise ParseStringError("invalid string literal for float()") - - try: - return parts_to_float(sign, before_point, after_point, exponent) - except ValueError: - raise ParseStringError("invalid string literal for float()") From tismer at codespeak.net Tue Aug 9 23:56:45 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 9 Aug 2005 23:56:45 +0200 (CEST) Subject: [pypy-svn] r15873 - pypy/dist/pypy/lib Message-ID: <20050809215645.92F5B27B3F@code1.codespeak.net> Author: tismer Date: Tue Aug 9 23:56:42 2005 New Revision: 15873 Modified: pypy/dist/pypy/lib/_float_formatting.py pypy/dist/pypy/lib/_formatting.py Log: some corrections that make _formatting and _float_formatting work correctly for marshal. May be re-enabled when other stuff is ready. Modified: pypy/dist/pypy/lib/_float_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_float_formatting.py (original) +++ pypy/dist/pypy/lib/_float_formatting.py Tue Aug 9 23:56:42 2005 @@ -16,6 +16,18 @@ # XXX should run this at interpreter level, really.... +def calc_mantissa_bits(): + bits = 1 # I know it is almost always 53, but let it compute... + while 1: + pattern = (1L << bits) - 1 + comp = long(float(pattern)) + if comp!= pattern: + return bits - 1 + bits += 1 + +MANTISSA_BITS = calc_mantissa_bits() +del calc_mantissa_bits + def decode_float(f): """decode_float(float) -> int, int @@ -23,8 +35,8 @@ f (assuming f is an IEEE double), i.e. f == m * 2**e and 2**52 <= m < 2**53.""" m, e = math.frexp(f) - m = long(m*2.0**53) - e -= 53 + m = long(m*2.0**MANTISSA_BITS) + e -= MANTISSA_BITS return m, e def decompose(f): @@ -38,7 +50,7 @@ the next smallest.""" m, e = decode_float(f) if e >= 0: - if not m != 2**52: + if not m != 2**(MANTISSA_BITS-1): be = 2**e return m*be*2, 2, be, be else: @@ -46,7 +58,7 @@ be1 = 2*be return m*be1*2, 4, be1, be else: - if e == -1075 or m != 2**52: + if e == -1075 or m != 2**(MANTISSA_BITS-1): return m*2, 2**(-e+1), 1, 1 else: return m*4, 2**(-e+2), 2, 1 Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Tue Aug 9 23:56:42 2005 @@ -251,7 +251,6 @@ if v/1e25 > 1e25: return FloatGFormatter('g', self.flags, self.width, self.prec, self.value).format() - return self._formatd('f', v) #ds, k = flonum2digits(v) #digits = self.fDigits(ds, k) @@ -259,13 +258,22 @@ # digits = digits.rstrip('.') #return digits +# system specific formatting. Linux does 3, Windows does 4... +# XXX this works only when we use geninterp! +if 0: + _x = `1.2e34` + _EF = len(_x) - _x.rindex('+') + del _x +else: + _EF = 3 + class FloatEFormatter(FloatFormatter): def _format(self, v): return self._formatd('e', v) #ds, k = flonum2digits(v) #digits = self.eDigits(ds) - #return "%s%c%+03d"%(digits, self.char, k-1) + #return "%%s%%c%%+0%dd" % _EF %(digits, self.char, k-1) class FloatGFormatter(FloatFormatter): @@ -275,9 +283,12 @@ # (One has to wonder who might care). def _format(self, v): return self._formatd('g', v) + ## the following is btw. correct for marshal, now: #ds, k = flonum2digits(v) #ds = ds[:self.prec] # XXX rounding! #if -4 < k <= self.prec: + # if k < 0: + # self.prec -= k # grow prec for extra zeros # digits = self.fDigits(ds, k) # if not self.flags.f_alt: # digits = digits.rstrip('0').rstrip('.') @@ -286,7 +297,7 @@ # digits = self.eDigits(ds) # if not self.flags.f_alt: # digits = digits.rstrip('0').rstrip('.') - # r = "%se%+03d"%(digits, k-1) + # r = "%%se%%+0%dd" % _EF %(digits, k-1) #return r From tismer at codespeak.net Tue Aug 9 23:58:24 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 9 Aug 2005 23:58:24 +0200 (CEST) Subject: [pypy-svn] r15874 - in pypy/dist/pypy: module/marshal module/marshal/test objspace/std Message-ID: <20050809215824.2508027B3F@code1.codespeak.net> Author: tismer Date: Tue Aug 9 23:58:20 2005 New Revision: 15874 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py pypy/dist/pypy/module/marshal/test/make_test_marshal.py pypy/dist/pypy/module/marshal/test/test_marshal.py pypy/dist/pypy/objspace/std/marshal_impl.py Log: changed marshal in several ways: - removed direct import of string_to_float - added buffer support - fixed int64 - added more tests passes test_marshal now. Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Tue Aug 9 23:58:20 2005 @@ -38,6 +38,11 @@ u = Unmarshaller(space, reader) return u.get_w_obj(False) +# even faster version using inlined string reader +def loads(space, w_str): + u = StringUnmarshaller(space, w_str) + return u.get_w_obj(False) + class _BaseWriter(object): pass @@ -101,6 +106,26 @@ return ''.join(self.buflis) +class StringWriter(_BaseWriter): + # actually we are writing to a stringlist + def __init__(self): + self.buflis = [''] + self.bufpos = 0 + + def write(self, data): + # append is not (yet) efficient, so we do our own allocation + #self.buflis.append(data) + pos = self.bufpos + if not pos & (pos-1) and pos > 0: + # power of two, double the buffer + self.buflis += self.buflis + self.buflis[pos] = data + self.bufpos = pos + 1 + + def get_value(self): + return ''.join(self.buflis[:self.bufpos]) + + class StringReader(_BaseReader): def __init__(self, space, w_str): self.space = space @@ -149,7 +174,7 @@ class Marshaller(_Base): # _annspecialcase_ = "specialize:ctr_location" # polymorphic # does not work with subclassing - + def __init__(self, space, writer, version): self.space = space ## self.put = putfunc @@ -343,7 +368,6 @@ def __init__(self, space, reader): self.space = space - ## self.get = getfunc self.reader = reader # account for the applevel that we will call by one more. self.nesting = ((space.getexecutioncontext().framestack.depth() + 1) @@ -354,6 +378,9 @@ assert n >= 0 return self.reader.read(n) + def get1(self): + return self.get(1) + def atom_str(self, typecode): self.start(typecode) lng = self.get_lng() @@ -370,7 +397,7 @@ return res def start(self, typecode): - tc = self.get(1) + tc = self.get1() if tc != typecode: self.raise_exc('invalid marshal data') self.typecode = tc @@ -405,7 +432,7 @@ return x def get_pascal(self): - lng = ord(self.get(1)) + lng = ord(self.get1()) return self.get(lng) def get_str(self): @@ -427,7 +454,7 @@ def get_w_obj(self, allow_null): self.nesting += 2 if self.nesting < nesting_limit: - tc = self.get(1) + tc = self.get1() w_ret = self._dispatch[ord(tc)](self.space, self, tc) if w_ret is None and not allow_null: space = self.space @@ -448,7 +475,7 @@ w_ret = space.w_None # something not None if self.nesting < nesting_limit: while idx < lng: - tc = self.get(1) + tc = self.get1() w_ret = self._dispatch[ord(tc)](space, self, tc) if w_ret is None: break @@ -469,3 +496,64 @@ def _run_stackless(self): self.raise_exc('object too deeply nested to unmarshal') + + +class StringUnmarshaller(Unmarshaller): + # Unmarshaller with inlined buffer string + def __init__(self, space, w_str): + Unmarshaller.__init__(self, space, None) + try: + self.bufstr = space.str_w(w_str) + except OperationError: + raise OperationError(space.w_TypeError, space.wrap( + 'marshal.loads() arg must be string')) + self.bufpos = 0 + self.limit = len(self.bufstr) + + def raise_eof(self): + space = self.space + raise OperationError(space.w_EOFError, space.wrap( + 'EOF read where object expected')) + + def get(self, n): + pos = self.bufpos + newpos = pos + n + if newpos > self.limit: + self.raise_eof() + self.bufpos = newpos + return self.bufstr[pos : newpos] + + def get1(self): + pos = self.bufpos + if pos >= self.limit: + self.raise_eof() + self.bufpos = pos + 1 + return self.bufstr[pos] + + def get_int(self): + pos = self.bufpos + newpos = pos + 4 + if newpos > self.limit: + self.raise_eof() + self.bufpos = newpos + a = ord(self.bufstr[pos]) + b = ord(self.bufstr[pos+1]) + c = ord(self.bufstr[pos+2]) + d = ord(self.bufstr[pos+3]) + x = a | (b<<8) | (c<<16) | (d<<24) + return intmask(x) + + def get_lng(self): + pos = self.bufpos + newpos = pos + 4 + if newpos > self.limit: + self.raise_eof() + self.bufpos = newpos + a = ord(self.bufstr[pos]) + b = ord(self.bufstr[pos+1]) + c = ord(self.bufstr[pos+2]) + d = ord(self.bufstr[pos+3]) + if d & 0x80: + self.raise_exc('bad marshal data') + x = a | (b<<8) | (c<<16) | (d<<24) + return x Modified: pypy/dist/pypy/module/marshal/test/make_test_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/test/make_test_marshal.py (original) +++ pypy/dist/pypy/module/marshal/test/make_test_marshal.py Tue Aug 9 23:58:20 2005 @@ -24,6 +24,8 @@ func.func_code scopefunc.func_code u'hello' + buffer(hello) + buffer(u'unicode, too') set() set([1, 2]) frozenset() @@ -33,8 +35,9 @@ def readable(s): for c, repl in ( ("'", '_quote_'), ('"', '_Quote_'), (':', '_colon_'), ('.', '_dot_'), - ('[', '_list_'), ('{', '_dict_'), ('-', '_minus_'), ('+', '_plus_'), - (',', '_comma_'), ('(', '_open_'), (')', '_close_') ): + ('[', '_list_'), (']', '_tsil_'), ('{', '_dict_'), ('}', '_tcid_'), + ('-', '_minus_'), ('+', '_plus_'), + (',', '_comma_'), ('(', '_brace_'), (')', '_ecarb_') ): s = s.replace(c, repl) lis = list(s) for i, c in enumerate(lis): @@ -63,7 +66,7 @@ scopefunc = func(42) import marshal, StringIO case = %(line)s - print "case:", case + print "case: %%-30s func=%(name)s" %% (case, ) s = marshal.dumps(case%(version)s)%(extra)s x = marshal.loads(s) assert x == case Modified: pypy/dist/pypy/module/marshal/test/test_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/test/test_marshal.py (original) +++ pypy/dist/pypy/module/marshal/test/test_marshal.py Tue Aug 9 23:58:20 2005 @@ -1,8 +1,4 @@ - class AppTestMarshal: - def setup_class(cls): - from pypy.objspace.std import StdObjSpace - cls.space = StdObjSpace(usemodules=["marshal"]) def test_None(self): import sys @@ -13,7 +9,7 @@ scopefunc = func(42) import marshal, StringIO case = None - print "case:", case + print "case: %-30s func=None" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -32,7 +28,7 @@ scopefunc = func(42) import marshal, StringIO case = False - print "case:", case + print "case: %-30s func=False" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -51,7 +47,7 @@ scopefunc = func(42) import marshal, StringIO case = True - print "case:", case + print "case: %-30s func=True" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -70,7 +66,7 @@ scopefunc = func(42) import marshal, StringIO case = StopIteration - print "case:", case + print "case: %-30s func=StopIteration" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -89,7 +85,7 @@ scopefunc = func(42) import marshal, StringIO case = Ellipsis - print "case:", case + print "case: %-30s func=Ellipsis" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -108,7 +104,7 @@ scopefunc = func(42) import marshal, StringIO case = 42 - print "case:", case + print "case: %-30s func=42" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -127,7 +123,7 @@ scopefunc = func(42) import marshal, StringIO case = sys.maxint - print "case:", case + print "case: %-30s func=sys_dot_maxint" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -146,7 +142,7 @@ scopefunc = func(42) import marshal, StringIO case = -1.25 - print "case:", case + print "case: %-30s func=_minus_1_dot_25" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -165,7 +161,7 @@ scopefunc = func(42) import marshal, StringIO case = -1.25 #2 - print "case:", case + print "case: %-30s func=_minus_1_dot_25__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) assert x == case @@ -184,7 +180,7 @@ scopefunc = func(42) import marshal, StringIO case = 2+5j - print "case:", case + print "case: %-30s func=2_plus_5j" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -203,7 +199,7 @@ scopefunc = func(42) import marshal, StringIO case = 2+5j #2 - print "case:", case + print "case: %-30s func=2_plus_5j__2" % (case, ) s = marshal.dumps(case, 2); assert len(s) in (9, 17) x = marshal.loads(s) assert x == case @@ -222,7 +218,7 @@ scopefunc = func(42) import marshal, StringIO case = 42L - print "case:", case + print "case: %-30s func=42L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -241,7 +237,7 @@ scopefunc = func(42) import marshal, StringIO case = -1234567890123456789012345678901234567890L - print "case:", case + print "case: %-30s func=_minus_1234567890123456789012345678901234567890L" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -260,7 +256,7 @@ scopefunc = func(42) import marshal, StringIO case = hello # not interned - print "case:", case + print "case: %-30s func=hello_____not_interned" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -279,7 +275,7 @@ scopefunc = func(42) import marshal, StringIO case = "hello" - print "case:", case + print "case: %-30s func=_Quote_hello_Quote_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -289,7 +285,7 @@ x = marshal.load(f) assert x == case - def test__open__close_(self): + def test__brace__ecarb_(self): import sys hello = "he" hello += "llo" @@ -298,7 +294,7 @@ scopefunc = func(42) import marshal, StringIO case = () - print "case:", case + print "case: %-30s func=_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -308,7 +304,7 @@ x = marshal.load(f) assert x == case - def test__open_1_comma__2_close_(self): + def test__brace_1_comma__2_ecarb_(self): import sys hello = "he" hello += "llo" @@ -317,7 +313,7 @@ scopefunc = func(42) import marshal, StringIO case = (1, 2) - print "case:", case + print "case: %-30s func=_brace_1_comma__2_ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -327,7 +323,7 @@ x = marshal.load(f) assert x == case - def test__list__(self): + def test__list__tsil_(self): import sys hello = "he" hello += "llo" @@ -336,7 +332,7 @@ scopefunc = func(42) import marshal, StringIO case = [] - print "case:", case + print "case: %-30s func=_list__tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -346,7 +342,7 @@ x = marshal.load(f) assert x == case - def test__list_3_comma__4_(self): + def test__list_3_comma__4_tsil_(self): import sys hello = "he" hello += "llo" @@ -355,7 +351,7 @@ scopefunc = func(42) import marshal, StringIO case = [3, 4] - print "case:", case + print "case: %-30s func=_list_3_comma__4_tsil_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -365,7 +361,7 @@ x = marshal.load(f) assert x == case - def test__dict__(self): + def test__dict__tcid_(self): import sys hello = "he" hello += "llo" @@ -374,7 +370,7 @@ scopefunc = func(42) import marshal, StringIO case = {} - print "case:", case + print "case: %-30s func=_dict__tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -384,7 +380,7 @@ x = marshal.load(f) assert x == case - def test__dict_5_colon__6_comma__7_colon__8_(self): + def test__dict_5_colon__6_comma__7_colon__8_tcid_(self): import sys hello = "he" hello += "llo" @@ -393,7 +389,7 @@ scopefunc = func(42) import marshal, StringIO case = {5: 6, 7: 8} - print "case:", case + print "case: %-30s func=_dict_5_colon__6_comma__7_colon__8_tcid_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -412,7 +408,7 @@ scopefunc = func(42) import marshal, StringIO case = func.func_code - print "case:", case + print "case: %-30s func=func_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -431,7 +427,7 @@ scopefunc = func(42) import marshal, StringIO case = scopefunc.func_code - print "case:", case + print "case: %-30s func=scopefunc_dot_func_code" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -450,7 +446,45 @@ scopefunc = func(42) import marshal, StringIO case = u'hello' - print "case:", case + print "case: %-30s func=u_quote_hello_quote_" % (case, ) + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_buffer_brace_hello_ecarb_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = buffer(hello) + print "case: %-30s func=buffer_brace_hello_ecarb_" % (case, ) + s = marshal.dumps(case) + x = marshal.loads(s) + assert x == case + f = StringIO.StringIO() + marshal.dump(case, f) + f.seek(0) + x = marshal.load(f) + assert x == case + + def test_buffer_brace_u_quote_unicode_comma__too_quote__ecarb_(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = buffer(u'unicode, too') + print "case: %-30s func=buffer_brace_u_quote_unicode_comma__too_quote__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -460,7 +494,7 @@ x = marshal.load(f) assert x == case - def test_set_open__close_(self): + def test_set_brace__ecarb_(self): import sys hello = "he" hello += "llo" @@ -469,7 +503,7 @@ scopefunc = func(42) import marshal, StringIO case = set() - print "case:", case + print "case: %-30s func=set_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -479,7 +513,7 @@ x = marshal.load(f) assert x == case - def test_set_open__list_1_comma__2__close_(self): + def test_set_brace__list_1_comma__2_tsil__ecarb_(self): import sys hello = "he" hello += "llo" @@ -488,7 +522,7 @@ scopefunc = func(42) import marshal, StringIO case = set([1, 2]) - print "case:", case + print "case: %-30s func=set_brace__list_1_comma__2_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -498,7 +532,7 @@ x = marshal.load(f) assert x == case - def test_frozenset_open__close_(self): + def test_frozenset_brace__ecarb_(self): import sys hello = "he" hello += "llo" @@ -507,7 +541,7 @@ scopefunc = func(42) import marshal, StringIO case = frozenset() - print "case:", case + print "case: %-30s func=frozenset_brace__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case @@ -517,7 +551,7 @@ x = marshal.load(f) assert x == case - def test_frozenset_open__list_3_comma__4__close_(self): + def test_frozenset_brace__list_3_comma__4_tsil__ecarb_(self): import sys hello = "he" hello += "llo" @@ -526,7 +560,7 @@ scopefunc = func(42) import marshal, StringIO case = frozenset([3, 4]) - print "case:", case + print "case: %-30s func=frozenset_brace__list_3_comma__4_tsil__ecarb_" % (case, ) s = marshal.dumps(case) x = marshal.loads(s) assert x == case Modified: pypy/dist/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/dist/pypy/objspace/std/marshal_impl.py (original) +++ pypy/dist/pypy/objspace/std/marshal_impl.py Tue Aug 9 23:58:20 2005 @@ -31,7 +31,6 @@ from pypy.objspace.std.unicodeobject import W_UnicodeObject import longobject, dictobject -from pypy.objspace.std.strutil import string_to_float from pypy.module.marshal.interp_marshal import register @@ -158,8 +157,8 @@ # for now, this rare case is solved the simple way. lshift = longobject.lshift__Long_Long longor = longobject.or__Long_Long - lo1 = space.newlong(u.get_short()) - lo2 = space.newlong(u.get_short()) + lo1 = space.newlong(u.get_short() & 0xffff) + lo2 = space.newlong(u.get_short() & 0xffff) res = space.newlong(u.get_int()) nbits = space.newlong(16) res = lshift(space, res, nbits) @@ -199,10 +198,10 @@ def unmarshal_Float(space, u, tc): if tc == TYPE_BINARY_FLOAT: w_ret = str_to_float(space, space.wrap(u.get(8))) - fl = space.float_w(w_ret) + return W_FloatObject(space, space.float_w(w_ret)) else: - fl = string_to_float(u.get_pascal()) - return W_FloatObject(space, fl) + return space.call_function(space.builtin.get('float'), + space.wrap(u.get_pascal())) register(TYPE_FLOAT + TYPE_BINARY_FLOAT, unmarshal_Float) # this is not a native type, yet, so we have to @@ -227,8 +226,10 @@ w_real = str_to_float(space, space.wrap(u.get(8))) w_imag = str_to_float(space, space.wrap(u.get(8))) else: - w_real = W_FloatObject(space, string_to_float(u.get_pascal())) - w_imag = W_FloatObject(space, string_to_float(u.get_pascal())) + w_real = space.call_function(space.builtin.get('float'), + space.wrap(u.get_pascal())) + w_imag = space.call_function(space.builtin.get('float'), + space.wrap(u.get_pascal())) w_t = space.builtin.get('complex') return space.call_function(w_t, w_real, w_imag) register(TYPE_COMPLEX + TYPE_BINARY_COMPLEX, unmarshal_Complex) @@ -427,6 +428,25 @@ return PyUnicode_DecodeUTF8(space, space.wrap(u.get_str())) register(TYPE_UNICODE, unmarshal_Unicode) +# not directly supported: +def marshal_w_buffer(space, w_buffer, m): + s = space.str_w(space.str(w_buffer)) + m.atom_str(TYPE_UNKNOWN, s) + +handled_by_any.append( ('buffer', marshal_w_buffer) ) + +app = gateway.applevel(r''' + def string_to_buffer(s): + return buffer(s) +''') + +string_to_buffer = app.interphook('string_to_buffer') + +def unmarshal_buffer(space, u, tc): + w_s = W_StringObject(space, u.get_str()) + return string_to_buffer(space, w_s) +register(TYPE_UNKNOWN, unmarshal_buffer) + app = gateway.applevel(r''' def set_to_list(theset): return [item for item in theset] From tismer at codespeak.net Wed Aug 10 00:11:45 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 10 Aug 2005 00:11:45 +0200 (CEST) Subject: [pypy-svn] r15875 - pypy/dist/pypy/objspace/std Message-ID: <20050809221145.E283827B46@code1.codespeak.net> Author: tismer Date: Wed Aug 10 00:11:44 2005 New Revision: 15875 Modified: pypy/dist/pypy/objspace/std/longobject.py Log: for the moment, fix longobject's SHIFT to be 15, in order not to break marshal. Later, think to make marshal pretend this. Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Wed Aug 10 00:11:44 2005 @@ -55,6 +55,11 @@ # Probably the primitive types will outperform this. SHIFT = (LONG_BIT // 2) - 1 + +# XXX +# SHIFT cannot be anything but 15 at the moment, or we break marshal +SHIFT = 15 + MASK = int((1 << SHIFT) - 1) From ericvrp at codespeak.net Wed Aug 10 00:13:09 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 10 Aug 2005 00:13:09 +0200 (CEST) Subject: [pypy-svn] r15876 - pypy/dist/pypy/translator Message-ID: <20050809221309.095C127B46@code1.codespeak.net> Author: ericvrp Date: Wed Aug 10 00:13:09 2005 New Revision: 15876 Modified: pypy/dist/pypy/translator/translator.py Log: forgot to check in... allows llvmcompile to generate standalones Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Wed Aug 10 00:13:09 2005 @@ -275,15 +275,30 @@ else: return genc.CExtModuleBuilder(self) - def llvmcompile(self, optimize=True): - """llvmcompile(self, optimize=True) -> LLVM translation + def llvmcompile(self, really_compile=True, standalone=False, optimize=True): + """llvmcompile(self, really_compile=True, standalone=False, optimize=True) -> LLVM translation Returns LLVM translation with or without optimization. """ from pypy.translator.llvm2 import genllvm if self.annotator is None: raise ValueError, "function has to be annotated." - return genllvm.genllvm(self) + self.frozen = True + return genllvm.genllvm(self, really_compile=really_compile, standalone=standalone, optimize=optimize) + + #self.frozen = True + #if standalone: + # builder = genllvm.LLVMStandaloneBuilder(self, optimize=optimize) + #else: + # builder = genllvm.LLVMExtModuleBuilder(self, optimize=optimize) + #source_filename = builder.generate_source() + #if not really_compile: + # return source_filename + #builder.compile() + #if standalone: + # return builder.executable_name + #builder.import_module() + #return builder.get_entry_point() def call(self, *args): """Calls underlying Python function.""" From nik at codespeak.net Wed Aug 10 00:34:43 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 10 Aug 2005 00:34:43 +0200 (CEST) Subject: [pypy-svn] r15877 - pypy/dist/pypy/module/_sre Message-ID: <20050809223443.28FAB27B49@code1.codespeak.net> Author: nik Date: Wed Aug 10 00:34:40 2005 New Revision: 15877 Added: pypy/dist/pypy/module/_sre/interp_sre.py (contents, props changed) Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py Log: converted some obvious candidate functions to interp-level. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Wed Aug 10 00:34:40 2005 @@ -18,4 +18,8 @@ } interpleveldefs = { + '_is_digit': 'interp_sre._is_digit', + '_is_space': 'interp_sre._is_space', + '_is_word': 'interp_sre._is_word', + '_is_linebreak': 'interp_sre._is_linebreak', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Wed Aug 10 00:34:40 2005 @@ -11,6 +11,7 @@ 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 +import _sre from _sre import CODESIZE @@ -500,7 +501,7 @@ return self.string_position == self.state.end def at_linebreak(self): - return not self.at_end() and _is_linebreak(self.peek_char()) + return not self.at_end() and _sre._is_linebreak(self.peek_char()) def at_boundary(self, word_checker): if self.at_beginning() and self.at_end(): @@ -1157,7 +1158,7 @@ return ctx.at_beginning() at_beginning_string = at_beginning def at_beginning_line(self, ctx): - return ctx.at_beginning() or _is_linebreak(ctx.peek_char(-1)) + return ctx.at_beginning() or _sre._is_linebreak(ctx.peek_char(-1)) def at_end(self, ctx): return (ctx.remaining_chars() == 1 and ctx.at_linebreak()) or ctx.at_end() def at_end_line(self, ctx): @@ -1165,9 +1166,9 @@ def at_end_string(self, ctx): return ctx.at_end() def at_boundary(self, ctx): - return ctx.at_boundary(_is_word) + return ctx.at_boundary(_sre._is_word) def at_non_boundary(self, ctx): - return not ctx.at_boundary(_is_word) + return not ctx.at_boundary(_sre._is_word) def at_loc_boundary(self, ctx): return ctx.at_boundary(_is_loc_word) def at_loc_non_boundary(self, ctx): @@ -1185,21 +1186,21 @@ class _ChcodeDispatcher(_Dispatcher): def category_digit(self, ctx): - return _is_digit(ctx.peek_char()) + return _sre._is_digit(ctx.peek_char()) def category_not_digit(self, ctx): - return not _is_digit(ctx.peek_char()) + return not _sre._is_digit(ctx.peek_char()) def category_space(self, ctx): - return _is_space(ctx.peek_char()) + return _sre._is_space(ctx.peek_char()) def category_not_space(self, ctx): - return not _is_space(ctx.peek_char()) + return not _sre._is_space(ctx.peek_char()) def category_word(self, ctx): - return _is_word(ctx.peek_char()) + return _sre._is_word(ctx.peek_char()) def category_not_word(self, ctx): - return not _is_word(ctx.peek_char()) + return not _sre._is_word(ctx.peek_char()) def category_linebreak(self, ctx): - return _is_linebreak(ctx.peek_char()) + return _sre._is_linebreak(ctx.peek_char()) def category_not_linebreak(self, ctx): - return not _is_linebreak(ctx.peek_char()) + return not _sre._is_linebreak(ctx.peek_char()) def category_loc_word(self, ctx): return _is_loc_word(ctx.peek_char()) def category_loc_not_word(self, ctx): @@ -1226,36 +1227,12 @@ _ChcodeDispatcher.build_dispatch_table(CHCODES, "") -_ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, -2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, -0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 ] - -def _is_digit(char): - code = ord(char) - return code < 128 and _ascii_char_info[code] & 1 - -def _is_space(char): - code = ord(char) - return code < 128 and _ascii_char_info[code] & 2 - -def _is_word(char): - # NB: non-ASCII chars aren't words according to _sre.c - code = ord(char) - return code < 128 and _ascii_char_info[code] & 16 - def _is_loc_word(char): return (not (ord(char) & ~255) and char.isalnum()) or char == '_' def _is_uni_word(char): return char.isalnum() or char == '_' -def _is_linebreak(char): - return char == "\n" - # Static list of all unicode codepoints reported by Py_UNICODE_ISLINEBREAK. _uni_linebreaks = [10, 13, 28, 29, 30, 133, 8232, 8233] Added: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/interp_sre.py Wed Aug 10 00:34:40 2005 @@ -0,0 +1,26 @@ +from pypy.interpreter.baseobjspace import ObjSpace + +_ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, +2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, +0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 ] + +_linebreak = ord("\n") + +def _is_digit(space, w_char): + code = space.int_w(space.ord(w_char)) + return space.newbool(code < 128 and _ascii_char_info[code] & 1) + +def _is_space(space, w_char): + code = space.int_w(space.ord(w_char)) + return space.newbool(code < 128 and _ascii_char_info[code] & 2) + +def _is_word(space, w_char): + code = space.int_w(space.ord(w_char)) + return space.newbool(code < 128 and _ascii_char_info[code] & 16) + +def _is_linebreak(space, w_char): + return space.newbool(space.int_w(space.ord(w_char)) == _linebreak) From tismer at codespeak.net Wed Aug 10 00:46:28 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 10 Aug 2005 00:46:28 +0200 (CEST) Subject: [pypy-svn] r15878 - in pypy/dist/pypy: module/__builtin__ objspace/std Message-ID: <20050809224628.E332727B49@code1.codespeak.net> Author: tismer Date: Wed Aug 10 00:46:28 2005 New Revision: 15878 Modified: pypy/dist/pypy/module/__builtin__/importing.py pypy/dist/pypy/objspace/std/objspace.py Log: enabled .pyc files, again, after it appears to work. Hopefully nothing breaks, again! Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Wed Aug 10 00:46:28 2005 @@ -30,7 +30,7 @@ import stat -PYC_ONOFF = False +PYC_ONOFF = True def info_modtype(space ,filepart): """ Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Aug 10 00:46:28 2005 @@ -84,8 +84,7 @@ self.setup_old_style_classes() # early bootstrap for marshal - if 0: # DISABLED PYC FILES FOR NOW - self.sys.setmodule(self.setup_marshal()) + self.sys.setmodule(self.setup_marshal()) # fix up a problem where multimethods apparently don't # like to define this at interp-level From tismer at codespeak.net Wed Aug 10 00:52:37 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 10 Aug 2005 00:52:37 +0200 (CEST) Subject: [pypy-svn] r15879 - pypy/dist/pypy/objspace/std Message-ID: <20050809225237.6A3C927B46@code1.codespeak.net> Author: tismer Date: Wed Aug 10 00:52:35 2005 New Revision: 15879 Modified: pypy/dist/pypy/objspace/std/strutil.py Log: harmonizing the error messages a bit with CPython Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Wed Aug 10 00:52:35 2005 @@ -35,7 +35,7 @@ if self.literal: raise ParseStringError, 'invalid literal for %s(): %s' % (self.fname, self.literal) else: - raise ParseStringError, 'empty literal for %s()' % (self.fname,) + raise ParseStringError, 'empty string for %s()' % (self.fname,) def __init__(self, s, literal, base, fname): self.literal = literal @@ -168,25 +168,25 @@ return sign, before_point, after_point, exponent if s[i] not in 'eE': - raise ParseStringError("invalid string literal for float()") + raise ParseStringError("invalid literal for float()") i += 1 if i == len(s): - raise ParseStringError("invalid string literal for float()") + raise ParseStringError("invalid literal for float()") if s[i] in '-+': exponent += s[i] i += 1 if i == len(s): - raise ParseStringError("invalid string literal for float()") + raise ParseStringError("invalid literal for float()") while i < len(s) and s[i] in '0123456789': exponent += s[i] i += 1 if i != len(s): - raise ParseStringError("invalid string literal for float()") + raise ParseStringError("invalid literal for float()") return sign, before_point, after_point, exponent @@ -207,12 +207,12 @@ sign, before_point, after_point, exponent = break_up_float(s) if not before_point and not after_point: - raise ParseStringError("invalid string literal for float()") + raise ParseStringError("invalid literal for float()") try: return parts_to_float(sign, before_point, after_point, exponent) except ValueError: - raise ParseStringError("invalid string literal for float()") + raise ParseStringError("invalid literal for float()") # Tim's comment: @@ -237,6 +237,7 @@ del calc_mantissa_bits MANTISSA_DIGITS = len(str( (1L << MANTISSA_BITS)-1 )) + 1 +# we keep this version for reference. def applevel_string_to_float(s): """ Conversion of string to float. @@ -293,7 +294,7 @@ sign, before_point, after_point, exponent = break_up_float(s) if not before_point and not after_point: - raise ParseStringError("invalid string literal for float()") + raise ParseStringError("invalid literal for float()") # 2) pre-calculate digit exponent dexp. dexp = len(before_point) From pedronis at codespeak.net Wed Aug 10 01:13:55 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 01:13:55 +0200 (CEST) Subject: [pypy-svn] r15883 - pypy/dist/pypy/objspace/std Message-ID: <20050809231355.547CE27B46@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 01:13:54 2005 New Revision: 15883 Modified: pypy/dist/pypy/objspace/std/dicttype.py Log: don't use space.wrap on types Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Wed Aug 10 01:13:54 2005 @@ -19,7 +19,8 @@ dict_reversed = MultiMethod('__reversed__', 1) def dict_reversed__ANY(space, w_dict): - raise OperationError(space.wrap(TypeError),space.wrap('argument to reversed() must be a sequence')) + raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence')) + #dict_fromkeys = MultiMethod('fromkeys', 2, varargs=True) # This can return when multimethods have been fixed #dict_str = StdObjSpace.str From tismer at codespeak.net Wed Aug 10 02:00:46 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 10 Aug 2005 02:00:46 +0200 (CEST) Subject: [pypy-svn] r15884 - pypy/dist/pypy/objspace/std Message-ID: <20050810000046.B14B127B46@code1.codespeak.net> Author: tismer Date: Wed Aug 10 02:00:44 2005 New Revision: 15884 Modified: pypy/dist/pypy/objspace/std/objspace.py Log: sorryfor enabling the old marshal, too, by chance. removed the oldgeninterp marshal support for this, completely. Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Aug 10 02:00:44 2005 @@ -83,9 +83,6 @@ self.w_instance = W_TypeObject(self, 'instance', [self.w_object], {}) self.setup_old_style_classes() - # early bootstrap for marshal - self.sys.setmodule(self.setup_marshal()) - # fix up a problem where multimethods apparently don't # like to define this at interp-level self.appexec([self.w_dict], """ @@ -134,10 +131,6 @@ self.w_classobj = w_classobj self.w_instance = w_instance - def setup_marshal(self): - w_mod, w_dic = self.create_builtin_module('_marshal.py', 'marshal') - return w_mod - def create_builtin_module(self, pyname, publicname): """NOT_RPYTHON helper function which returns the wrapped module and its dict. From tismer at codespeak.net Wed Aug 10 02:29:05 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 10 Aug 2005 02:29:05 +0200 (CEST) Subject: [pypy-svn] r15885 - pypy/dist/pypy/rpython Message-ID: <20050810002905.3F2C327B46@code1.codespeak.net> Author: tismer Date: Wed Aug 10 02:29:04 2005 New Revision: 15885 Modified: pypy/dist/pypy/rpython/rstr.py Log: detabbified Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Wed Aug 10 02:29:04 2005 @@ -887,43 +887,43 @@ def ll_int(s, base): if not 2 <= base <= 36: - raise ValueError + raise ValueError chars = s.chars strlen = len(chars) i = 0 #XXX: only space is allowed as white space for now while i < strlen and chars[i] == ' ': - i += 1 + i += 1 if not i < strlen: - raise ValueError + raise ValueError #check sign sign = 1 if chars[i] == '-': - sign = -1 - i += 1 + sign = -1 + i += 1 elif chars[i] == '+': - i += 1; + i += 1; #now get digits val = 0 while i < strlen: - c = ord(chars[i]) - if ord('a') <= c <= ord('z'): - digit = c - ord('a') + 10 - elif ord('A') <= c <= ord('Z'): - digit = c - ord('A') + 10 - elif ord('0') <= c <= ord('9'): - digit = c - ord('0') - else: - break - if digit >= base: - break - val = val * base + digit - i += 1 + c = ord(chars[i]) + if ord('a') <= c <= ord('z'): + digit = c - ord('a') + 10 + elif ord('A') <= c <= ord('Z'): + digit = c - ord('A') + 10 + elif ord('0') <= c <= ord('9'): + digit = c - ord('0') + else: + break + if digit >= base: + break + val = val * base + digit + i += 1 #skip trailing whitespace while i < strlen and chars[i] == ' ': - i += 1 + i += 1 if not i == strlen: - raise ValueError + raise ValueError return sign * val # ____________________________________________________________ From pedronis at codespeak.net Wed Aug 10 02:36:35 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 02:36:35 +0200 (CEST) Subject: [pypy-svn] r15886 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050810003635.22A6627B46@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 02:36:34 2005 New Revision: 15886 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Log: the new hack is always required Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_samples.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Wed Aug 10 02:36:34 2005 @@ -107,13 +107,13 @@ repr_pypy = repr_pypy.replace("Function(None, ", "Function(") repr_python = repr_python.replace("Function(None, ", "Function(") # XXX hack(bis): - # we changed stablecompiler to use [] instead of () in several - # places (for consistency), so let's make sure the test won't fail - # because of that (the workaround is as drastic as the way we - # compare python and pypy tuples :-), but we'll change that with - # astbuilder.py - repr_pypy = repr_pypy.replace("[]", "()") - repr_python = repr_python.replace("[]", "()") + # we changed stablecompiler to use [] instead of () in several + # places (for consistency), so let's make sure the test won't fail + # because of that (the workaround is as drastic as the way we + # compare python and pypy tuples :-), but we'll change that with + # astbuilder.py + repr_pypy = repr_pypy.replace("[]", "()") + repr_python = repr_python.replace("[]", "()") assert repr_pypy == repr_python From pedronis at codespeak.net Wed Aug 10 02:40:09 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 02:40:09 +0200 (CEST) Subject: [pypy-svn] r15887 - pypy/dist/pypy/lib/test2 Message-ID: <20050810004009.CB58E27B49@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 02:40:08 2005 New Revision: 15887 Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py Log: more hacking to get the test working on Python2.3 too with the current code in collections.py Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_deque_extra.py (original) +++ pypy/dist/pypy/lib/test2/test_deque_extra.py Wed Aug 10 02:40:08 2005 @@ -5,7 +5,16 @@ reversed except NameError: def reversed(seq): # fall-back - return seq.__reversed__() + if hasattr(seq, '__reversed__'): + return seq.__reversed__() + def gen(): + i = len(seq)-1 + while i >= 0: + yield seq[i] + i -= 1 + return gen() + import pypy.lib.collections + pypy.lib.collections.reversed = reversed n = 10 class Test_deque: From rxe at codespeak.net Wed Aug 10 02:43:11 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 10 Aug 2005 02:43:11 +0200 (CEST) Subject: [pypy-svn] r15888 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050810004311.E7BE327B49@code1.codespeak.net> Author: rxe Date: Wed Aug 10 02:43:09 2005 New Revision: 15888 Modified: pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: Small tweak for uint_invert to work python2.3 and hacks to enable test. Also (cosmetic) remove old comment. Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 10 02:43:09 2005 @@ -165,7 +165,7 @@ self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), - str((1<<32)-1)) + str((1L<<32) - 1)) def binaryop(self, op): name = self.binary_operations[op.opname] Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Wed Aug 10 02:43:09 2005 @@ -7,8 +7,6 @@ from pypy.translator.llvm2.genllvm import compile_function def test_call_five(): - # -- the result of call_five() isn't a real list, but an rlist - # that can't be converted to a PyListObject def wrapper(): lst = snippet.call_five() res = list((len(lst), lst[0])) @@ -328,14 +326,19 @@ def fn(i): return ~i f = compile_function(fn, [int]) - for i in range(-15,15): + for i in range(-15, 15): assert f(i) == fn(i) def test_uint_invert(): - py.test.skip("not sure why uint annotated function can return -1 (pyrex?)") def fn(i): - return ~i + inverted = ~i + inverted -= sys.maxint + return inverted f = compile_function(fn, [r_uint]) - for value in range(15): + for value in range(1, 15): + i = r_uint(value) + assert str(f(i)) == str(fn(i)) + s = 0xfffffff + for value in range(s, s+1024, 64): i = r_uint(value) assert str(f(i)) == str(fn(i)) From pedronis at codespeak.net Wed Aug 10 02:43:37 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 02:43:37 +0200 (CEST) Subject: [pypy-svn] r15889 - pypy/dist/pypy/annotation Message-ID: <20050810004337.DFF0627B49@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 02:43:36 2005 New Revision: 15889 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/unaryop.py Log: typed iter cannot raise TypeError no OverflowError from inplace ops Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Wed Aug 10 02:43:36 2005 @@ -92,6 +92,15 @@ def inplace_or((obj1, obj2)): return pair(obj1, obj2).or_() def inplace_xor((obj1, obj2)): return pair(obj1, obj2).xor() + for name, func in locals().items(): + if name.startswith('inplace_'): + func.can_only_throw = [] + + inplace_div.can_only_throw = [ZeroDivisionError] + inplace_truediv.can_only_throw = [ZeroDivisionError] + inplace_floordiv.can_only_throw = [ZeroDivisionError] + inplace_mod.can_only_throw = [ZeroDivisionError] + def lt((obj1, obj2)): if obj1.is_constant() and obj2.is_constant(): return immutablevalue(obj1.const < obj2.const) @@ -335,6 +344,7 @@ lst1.listdef.resize() lst1.listdef.union(lst2.listdef) return lst1 + inplace_add.can_only_throw = [] def eq((lst1, lst2)): lst1.listdef.union(lst2.listdef) @@ -349,11 +359,12 @@ s_iter = obj2.iter() pair(lst1, SomeInteger()).setitem(s_iter.next()) return lst1 + inplace_add.can_only_throw = [] def inplace_mul((lst1, obj2)): lst1.listdef.resize() return lst1 - + inplace_mul.can_only_throw = [] class __extend__(pairtype(SomeTuple, SomeTuple)): Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Wed Aug 10 02:43:36 2005 @@ -212,6 +212,7 @@ def iter(tup): getbookkeeper().count("tuple_iter", tup) return SomeIterator(tup) + iter.can_only_throw = [] def getanyitem(tup): return unionof(*tup.items) @@ -254,6 +255,7 @@ def iter(lst): return SomeIterator(lst) + iter.can_only_throw = [] def getanyitem(lst): return lst.listdef.read_item() @@ -269,6 +271,7 @@ def iter(dct): return SomeIterator(dct) + iter.can_only_throw = [] def getanyitem(dct): return dct.dictdef.read_key() @@ -315,6 +318,7 @@ def iter(str): return SomeIterator(str) + iter.can_only_throw = [] def getanyitem(str): return SomeChar() @@ -357,6 +361,7 @@ def iter(itr): return itr + iter.can_only_throw = [] def next(itr): return itr.s_container.getanyitem() From tismer at codespeak.net Wed Aug 10 02:51:21 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 10 Aug 2005 02:51:21 +0200 (CEST) Subject: [pypy-svn] r15890 - pypy/dist/pypy/objspace/std Message-ID: <20050810005121.8BC1427B49@code1.codespeak.net> Author: tismer Date: Wed Aug 10 02:51:20 2005 New Revision: 15890 Modified: pypy/dist/pypy/objspace/std/longobject.py Log: a small little routine that turns an already correctly parsed decimal string quickly into along. Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Wed Aug 10 02:51:20 2005 @@ -1619,3 +1619,42 @@ i -= 1 x = intmask(x * sign) return x + +#_________________________________________________________________ + +# a few internal helpers + +DEC_PER_DIGIT = 1 +while int('9' * DEC_PER_DIGIT) < MASK: + DEC_PER_DIGIT += 1 +DEC_PER_DIGIT -= 1 +DEC_MAX = 10 ** DEC_PER_DIGIT + +def _decimalstr_to_long(space, s): + # a string that has been already parsed to be decimal and valid, + # is turned into a long + p = 0 + lim = len(s) + sign = False + if s[p] == '-': + sign = True + p += 1 + elif s[p] == '+': + p += 1 + + a = W_LongObject(space, [0], 1) + cnt = DEC_PER_DIGIT + tens = 1 + dig = 0 + ord0 = ord('0') + while p < lim: + dig = dig * 10 + ord(s[p]) - ord0 + p += 1 + tens *= 10 + if tens == DEC_MAX or p == lim: + a = _muladd1(a, tens, dig) + tens = 1 + dig = 0 + if sign: + a.sign = -1 + return a From pedronis at codespeak.net Wed Aug 10 03:24:57 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 03:24:57 +0200 (CEST) Subject: [pypy-svn] r15891 - pypy/dist/pypy/rpython Message-ID: <20050810012457.C83DF27B48@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 03:24:52 2005 New Revision: 15891 Modified: pypy/dist/pypy/rpython/rlist.py Log: builin method invocation goes through a simple_call, so exception exits can get attached; but list.append will not raise exceptions Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Wed Aug 10 03:24:52 2005 @@ -103,6 +103,7 @@ def rtype_method_append(self, hop): v_lst, v_value = hop.inputargs(self, self.item_repr) + hop.exception_cannot_occur() hop.gendirectcall(ll_append, v_lst, v_value) def rtype_method_index(self, hop): From tismer at codespeak.net Wed Aug 10 03:34:58 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 10 Aug 2005 03:34:58 +0200 (CEST) Subject: [pypy-svn] r15892 - pypy/dist/pypy/objspace/std Message-ID: <20050810013458.C984227B41@code1.codespeak.net> Author: tismer Date: Wed Aug 10 03:34:57 2005 New Revision: 15892 Modified: pypy/dist/pypy/objspace/std/longobject.py Log: small helpertoget the number of bits in a long Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Wed Aug 10 03:34:57 2005 @@ -1658,3 +1658,15 @@ if sign: a.sign = -1 return a + +def _count_bits(a): + # return the number of bits in the digits + if a.sign == 0: + return 0 + p = len(a.digits) - 1 + bits = SHIFT * p + digit = a.digits[p] + while digit: + digit >>= 1 + bits += 1 + return bits From adim at codespeak.net Wed Aug 10 09:01:58 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 10 Aug 2005 09:01:58 +0200 (CEST) Subject: [pypy-svn] r15893 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20050810070158.2B95327B46@code1.codespeak.net> Author: adim Date: Wed Aug 10 09:01:51 2005 New Revision: 15893 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py Log: slight modification of the way nodes are compared Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Wed Aug 10 09:01:51 2005 @@ -34,7 +34,13 @@ def visit(self, visitor, *args): return visitor.visitNode(self, *args) def __eq__(self, right): - if type(self)!=type(right): + if type(self) != type(right): + return False + # the following tests prevnts Node1([foo]) and Node2([foo]) + # from being equals. compare __name__ because class will + # be different (astcompiler.class1 and stablecompiler.class1 should + # be seen as equals) + if self.__class__.__name__ != right.__class__.__name__: return False self_child = self.getChildren() right_child = right.getChildren() From adim at codespeak.net Wed Aug 10 09:02:28 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 10 Aug 2005 09:02:28 +0200 (CEST) Subject: [pypy-svn] r15894 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050810070228.58D8927B46@code1.codespeak.net> Author: adim Date: Wed Aug 10 09:02:26 2005 New Revision: 15894 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: implementecd prints/execs/asserts Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Aug 10 09:02:26 2005 @@ -612,6 +612,50 @@ assert isinstance(L[1], ast.Name), "build_del_stmt implementation is incomplete !" builder.push(ast.AssName(L[1].name, consts.OP_DELETE)) +def build_assert_stmt(builder, nb): + """assert_stmt: 'assert' test [',' test]""" + L = get_atoms(builder, nb) + test = L[1] + if len(L) == 4: + fail = L[3] + else: + fail = None + builder.push(ast.Assert(test, fail)) + +def build_exec_stmt(builder, nb): + """exec_stmt: 'exec' expr ['in' test [',' test]]""" + L = get_atoms(builder, nb) + expr = L[1] + loc = None + glob = None + if len(L) > 2: + loc = L[3] + if len(L) > 4: + glob = L[5] + builder.push(ast.Exec(expr, loc, glob)) + +def build_print_stmt(builder, nb): + """ + print_stmt: 'print' ( '>>' test [ (',' test)+ [','] ] | [ test (',' test)* [','] ] ) + """ + L = get_atoms(builder, nb) + l = len(L) + items = [] + dest = None + start = 1 + if l > 1: + if isinstance(L[1], TokenObject) and L[1].name == tok.RIGHTSHIFT: + dest = L[2] + # skip following comma + start = 4 + for index in range(start, l, 2): + items.append(L[index]) + if isinstance(L[-1], TokenObject) and L[-1].name == tok.COMMA: + builder.push(ast.Print(items, dest)) + else: + builder.push(ast.Printnl(items, dest)) + + def parse_dotted_names(tokens): """parses NAME('.' NAME)* and returns full dotted name @@ -815,6 +859,9 @@ sym.yield_stmt : build_yield_stmt, sym.continue_stmt : build_continue_stmt, sym.del_stmt : build_del_stmt, + sym.assert_stmt : build_assert_stmt, + sym.exec_stmt : build_exec_stmt, + sym.print_stmt : build_print_stmt, # sym.parameters : build_parameters, } Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 10 09:02:26 2005 @@ -131,6 +131,32 @@ """ ] +asserts = [ + 'assert False', + 'assert a == 1', + 'assert a == 1 and b == 2', + 'assert a == 1 and b == 2, "assertion failed"', + ] + +execs = [ + 'exec a', + 'exec "a=b+3"', + 'exec a in f()', + 'exec a in f(), g()', + ] + +prints = [ + 'print', + 'print a', + 'print a,', + 'print a, b', + 'print a, "b", c', + 'print >> err', + 'print >> err, "error"', + 'print >> err, "error",', + 'print >> err, "error", a', + ] + one_stmt_funcdefs = [ "def f(): return 1", "def f(x): return x+1", @@ -154,6 +180,9 @@ multiexpr, attraccess, imports, + asserts, + execs, + prints ] EXEC_INPUTS = [ From adim at codespeak.net Wed Aug 10 09:10:38 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 10 Aug 2005 09:10:38 +0200 (CEST) Subject: [pypy-svn] r15895 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050810071038.3048527B46@code1.codespeak.net> Author: adim Date: Wed Aug 10 09:10:36 2005 New Revision: 15895 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: global statements reducing Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Aug 10 09:10:36 2005 @@ -655,6 +655,15 @@ else: builder.push(ast.Printnl(items, dest)) +def build_global_stmt(builder, nb): + """global_stmt: 'global' NAME (',' NAME)*""" + L = get_atoms(builder, nb) + names = [] + for index in range(1, len(L), 2): + token = L[index] + assert isinstance(token, TokenObject) + names.append(token.value) + builder.push(ast.Global(names)) def parse_dotted_names(tokens): """parses NAME('.' NAME)* and returns full dotted name @@ -862,6 +871,7 @@ sym.assert_stmt : build_assert_stmt, sym.exec_stmt : build_exec_stmt, sym.print_stmt : build_print_stmt, + sym.global_stmt : build_global_stmt, # sym.parameters : build_parameters, } Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 10 09:10:36 2005 @@ -157,6 +157,11 @@ 'print >> err, "error", a', ] +globs = [ + 'global a', + 'global a,b,c', + ] + one_stmt_funcdefs = [ "def f(): return 1", "def f(x): return x+1", @@ -182,7 +187,8 @@ imports, asserts, execs, - prints + prints, + globs, ] EXEC_INPUTS = [ From adim at codespeak.net Wed Aug 10 10:46:36 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 10 Aug 2005 10:46:36 +0200 (CEST) Subject: [pypy-svn] r15896 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050810084636.E068A27B46@code1.codespeak.net> Author: adim Date: Wed Aug 10 10:46:34 2005 New Revision: 15896 Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_exceptions.py Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: implemented try/except/finally/raise Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Aug 10 10:46:34 2005 @@ -665,6 +665,79 @@ names.append(token.value) builder.push(ast.Global(names)) + +def build_raise_stmt(builder, nb): + """raise_stmt: 'raise' [test [',' test [',' test]]]""" + L = get_atoms(builder, nb) + l = len(L) + expr1 = None + expr2 = None + expr3 = None + if l >= 2: + expr1 = L[1] + if l >= 4: + expr2 = L[3] + if l == 6: + expr3 = L[5] + builder.push(ast.Raise(expr1, expr2, expr3)) + +def build_try_stmt(builder, nb): + """ + try_stmt: ('try' ':' suite (except_clause ':' suite)+ #diagram:break + ['else' ':' suite] | 'try' ':' suite 'finally' ':' suite) + # NB compile.c makes sure that the default except clause is last + except_clause: 'except' [test [',' test]] + + """ + L = get_atoms(builder, nb) + l = len(L) + handlers = [] + else_ = None + body = L[2] + token = L[3] + assert isinstance(token, TokenObject) + if token.value == 'finally': + builder.push(ast.TryFinally(body, L[5])) + else: # token.value == 'except' + index = 3 + while index < l and L[index].value == 'except': + tokens_read, expr1, expr2, except_body = parse_except_clause(L[index:]) + handlers.append((expr1, expr2, except_body)) + index += tokens_read + if index < l: + token = L[index] + assert isinstance(token, TokenObject) + assert token.value == 'else' + else_ = L[index+2] # skip ':' + builder.push(ast.TryExcept(body, handlers, else_)) + + +def parse_except_clause(tokens): + """parses 'except' [test [',' test]] ':' suite + and returns a 4-tuple : (tokens_read, expr1, expr2, except_body) + """ + clause_length = 1 + # Read until end of except clause (bound by following 'else', + # or 'except' or end of tokens) + while clause_length < len(tokens): + token = tokens[clause_length] + if isinstance(token, TokenObject) and \ + (token.value == 'except' or token.value == 'else'): + break + clause_length += 1 + # if clause_length >= len(tokens): + # raise Exception + if clause_length == 3: + # case 'except: body' + return (3, None, None, tokens[2]) + elif clause_length == 4: + # case 'except Exception: body': + return (4, tokens[1], None, tokens[3]) + else: + # case 'except Exception, exc: body' + return (6, tokens[1], to_lvalue(tokens[3], consts.OP_ASSIGN), tokens[5]) + + def parse_dotted_names(tokens): """parses NAME('.' NAME)* and returns full dotted name @@ -872,6 +945,8 @@ sym.exec_stmt : build_exec_stmt, sym.print_stmt : build_print_stmt, sym.global_stmt : build_global_stmt, + sym.raise_stmt : build_raise_stmt, + sym.try_stmt : build_try_stmt, # sym.parameters : build_parameters, } Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_exceptions.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_exceptions.py Wed Aug 10 10:46:34 2005 @@ -0,0 +1,54 @@ +try: + a + b +except: + pass + +try: + a + b +except NameError: + pass + +try: + a + b +except NameError, err: + pass + +try: + a + b +except (NameError, ValueError): + pass + + +try: + a + b +except (NameError, ValueError), err: + pass + +try: + a +except NameError, err: + pass +except ValueError, err: + pass + +try: + a +except NameError, err: + pass +except ValueError, err: + pass +else: + pass + +try: + a +finally: + b + + + Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 10 10:46:34 2005 @@ -162,6 +162,84 @@ 'global a,b,c', ] +raises = [ + 'raise', + 'raise ValueError', + 'raise ValueError("error")', + 'raise ValueError, "error"', + 'raise ValueError, "error", foo', + ] + +tryexcepts = [ + """try: + a + b +except: + pass +""", + """try: + a + b +except NameError: + pass +""", + """try: + a + b +except NameError, err: + pass +""", + """try: + a + b +except (NameError, ValueError): + pass +""", + """try: + a + b +except (NameError, ValueError), err: + pass +""", + """try: + a +except NameError, err: + pass +except ValueError, err: + pass +""", + """try: + a +except NameError, err: + a = 1 + b = 2 +except ValueError, err: + a = 2 + return a +""" + """try: + a +except NameError, err: + a = 1 +except ValueError, err: + a = 2 +else: + a += 3 +""", + """try: + a +finally: + b +""", + """try: + return a +finally: + a = 3 + return 1 +""", + + ] + one_stmt_funcdefs = [ "def f(): return 1", "def f(x): return x+1", @@ -189,11 +267,13 @@ execs, prints, globs, + raises, ] EXEC_INPUTS = [ one_stmt_funcdefs, if_stmts, + tryexcepts, ] TARGET_DICT = { @@ -242,6 +322,7 @@ 'snippet_while.py', 'snippet_import_statements.py', 'snippet_generator.py', + 'snippet_exceptions.py', # 'snippet_2.py', # 'snippet_3.py', # 'snippet_4.py', From arigo at codespeak.net Wed Aug 10 11:00:11 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Aug 2005 11:00:11 +0200 (CEST) Subject: [pypy-svn] r15898 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20050810090011.0339027B46@code1.codespeak.net> Author: arigo Date: Wed Aug 10 11:00:09 2005 New Revision: 15898 Modified: pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/module/__builtin__/test/test_functional.py Log: Compatibility fix: in CPython, reversed() only accepts a sequence as argument, not any iterable. Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Wed Aug 10 11:00:09 2005 @@ -341,15 +341,16 @@ sorted_lst.sort(cmp, key, reverse) return sorted_lst -def reversed(iterable): +def reversed(sequence): """reversed(sequence) -> reverse iterator over values of the sequence Return a reverse iterator """ - if hasattr(iterable, '__reversed__'): - return iterable.__reversed__() - seq = list(iterable) - return reversed_iterator(seq) + if hasattr(sequence, '__reversed__'): + return sequence.__reversed__() + if not hasattr(sequence, '__getitem__'): + raise TypeError("argument to reversed() must be a sequence") + return reversed_iterator(sequence) class reversed_iterator(object): Modified: pypy/dist/pypy/module/__builtin__/test/test_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_functional.py Wed Aug 10 11:00:09 2005 @@ -129,4 +129,5 @@ assert len(r) == 0 raises(StopIteration, r.next) assert len(r) == 0 - assert list(reversed(reversed("hello"))) == ['h', 'e', 'l', 'l', 'o'] + assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o'] + raises(TypeError, reversed, reversed("hello")) From arigo at codespeak.net Wed Aug 10 11:05:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 10 Aug 2005 11:05:02 +0200 (CEST) Subject: [pypy-svn] r15900 - pypy/dist/pypy/lib/test2 Message-ID: <20050810090502.E132427B46@code1.codespeak.net> Author: arigo Date: Wed Aug 10 11:05:00 2005 New Revision: 15900 Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py Log: The reimplementation of reversed() is now in the py lib, which has names in 'py.builtin.*' precisely for this kind of compatibility. Don't forget to 'svn up' at the level of the 'dist' directory to get the updated py lib. Modified: pypy/dist/pypy/lib/test2/test_deque_extra.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_deque_extra.py (original) +++ pypy/dist/pypy/lib/test2/test_deque_extra.py Wed Aug 10 11:05:00 2005 @@ -1,20 +1,10 @@ # Deque Tests # for passing the test on top of 2.3 -try: - reversed -except NameError: - def reversed(seq): # fall-back - if hasattr(seq, '__reversed__'): - return seq.__reversed__() - def gen(): - i = len(seq)-1 - while i >= 0: - yield seq[i] - i -= 1 - return gen() - import pypy.lib.collections - pypy.lib.collections.reversed = reversed +from py.builtin import reversed +import pypy.lib.collections +pypy.lib.collections.reversed = reversed + n = 10 class Test_deque: From adim at codespeak.net Wed Aug 10 11:17:06 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 10 Aug 2005 11:17:06 +0200 (CEST) Subject: [pypy-svn] r15901 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050810091706.1803127B48@code1.codespeak.net> Author: adim Date: Wed Aug 10 11:17:03 2005 New Revision: 15901 Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_classes.py Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: implemented class statements Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Aug 10 11:17:03 2005 @@ -442,7 +442,26 @@ code = L[-1] # FIXME: decorators and docstring ! builder.push(ast.Function(None, funcname, names, default, flags, None, code)) - + + +def build_classdef(builder, nb): + """classdef: 'class' NAME ['(' testlist ')'] ':' suite""" + L = get_atoms(builder, nb) + l = len(L) + # FIXME: docstring + classname = L[1].value + if l == 4: + basenames = [] + body = L[3] + elif l == 7: + basenames = [] + body = L[6] + base = L[3] + assert isinstance(base, ast.Tuple) + for node in base.nodes: + assert isinstance(node, ast.Name) + basenames.append(node) + builder.push(ast.Class(classname, basenames, None, body)) def build_suite(builder, nb): """suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT""" @@ -929,6 +948,7 @@ sym.arglist : build_arglist, sym.listmaker : build_listmaker, sym.funcdef : build_funcdef, + sym.classdef : build_classdef, sym.return_stmt : build_return_stmt, sym.suite : build_suite, sym.if_stmt : build_if_stmt, Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_classes.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_classes.py Wed Aug 10 11:17:03 2005 @@ -0,0 +1,12 @@ +class A: + def with_white_spaces_before(self): + pass + + def another_method(self, foo): + bar = foo + + +class B(object, A): + def foo(self, bar): + a = 2 + return "spam" Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 10 11:17:03 2005 @@ -323,6 +323,7 @@ 'snippet_import_statements.py', 'snippet_generator.py', 'snippet_exceptions.py', + 'snippet_classes.py', # 'snippet_2.py', # 'snippet_3.py', # 'snippet_4.py', From ericvrp at codespeak.net Wed Aug 10 13:38:30 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 10 Aug 2005 13:38:30 +0200 (CEST) Subject: [pypy-svn] r15907 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050810113830.4DBF727B51@code1.codespeak.net> Author: ericvrp Date: Wed Aug 10 13:38:29 2005 New Revision: 15907 Modified: pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: int_abs and float_abs Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Wed Aug 10 13:38:29 2005 @@ -29,7 +29,39 @@ """) -#prepage exceptions +#abs functions +extfunctions["%int_abs"] = ((), """ +fastcc int %int_abs(int %x) { +block0: + %cond1 = setge int %x, 0 + br bool %cond1, label %return_block, label %block1 +block1: + %x2 = sub int 0, %x + br label %return_block +return_block: + %result = phi int [%x, %block0], [%x2, %block1] + ret int %result +} + +""") + +extfunctions["%float_abs"] = ((), """ +fastcc double %float_abs(double %x) { +block0: + %cond1 = setge double %x, 0.0 + br bool %cond1, label %return_block, label %block1 +block1: + %x2 = sub double 0.0, %x + br label %return_block +return_block: + %result = phi double [%x, %block0], [%x2, %block1] + ret double %result +} + +""") + + +#prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ fastcc void %%__prepare_%(exc)s() { @@ -97,7 +129,7 @@ fastcc int %%int_abs_ovf(int %%x) { block0: %%cond1 = setge int %%x, 0 - br bool %%cond1, label %%return_block, label %%is_negative + br bool %%cond1, label %%return_block, label %%block1 block1: %%x2 = sub int 0, %%x %(ovf_test)s Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 10 13:38:29 2005 @@ -125,6 +125,16 @@ targetvar = self.db.repr_arg(op.result) self.codewriter.cast(targetvar, mult_type, res_val, mult_type) + def int_abs(self, op): + functionref = '%' + op.opname + ExternalFuncNode.used_external_functions[functionref] = True + self.codewriter.call(self.db.repr_arg(op.result), + self.db.repr_arg_type(op.result), + functionref, + [self.db.repr_arg(op.args[0])], + [self.db.repr_arg_type(op.args[0])]) + float_abs = int_abs + def int_pow(self, op): self._generic_pow(op, "1") uint_pow = int_pow Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Wed Aug 10 13:38:29 2005 @@ -342,3 +342,17 @@ for value in range(s, s+1024, 64): i = r_uint(value) assert str(f(i)) == str(fn(i)) + +def test_int_abs(): + def int_abs_(n): + return abs(n) + f = compile_function(int_abs_, [int]) + for i in (-25, 0, 75): + assert f(i) == int_abs_(i) + +def test_float_abs(): + def float_abs_(n): + return abs(n) + f = compile_function(float_abs_, [float]) + for i in (-100.1 -50.2, -0.0, 0.0, 25.3, 50.4): + assert f(i) == float_abs_(i) From adim at codespeak.net Wed Aug 10 14:03:10 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 10 Aug 2005 14:03:10 +0200 (CEST) Subject: [pypy-svn] r15908 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050810120310.6235927B5B@code1.codespeak.net> Author: adim Date: Wed Aug 10 14:03:05 2005 New Revision: 15908 Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_docstring.py Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - implemented subscript (indexation and slices) - fetch docstring - added lvalue support for attraccess and subscripts Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Aug 10 14:03:05 2005 @@ -20,6 +20,13 @@ for node in ast_node.getChildren(): nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssTuple(nodes) + elif isinstance(ast_node, ast.Getattr): + expr = ast_node.expr + attrname = ast_node.attrname + return ast.AssAttr(expr, attrname, OP) + elif isinstance(ast_node, ast.Subscript): + ast_node.flags = OP + return ast_node else: assert False, "TODO" @@ -119,8 +126,21 @@ if len(L) == 1: builder.push( L[0] ) elif len(L) == 2: - arguments, stararg, dstararg = L[1].value - builder.push(ast.CallFunc(L[0], arguments, stararg, dstararg)) + if isinstance(L[1], ArglistObject): + arguments, stararg, dstararg = L[1].value + builder.push(ast.CallFunc(L[0], arguments, stararg, dstararg)) + elif isinstance(L[1], SubscriptObject): + subs = L[1].value + builder.push(ast.Subscript(L[0], consts.OP_APPLY, subs)) + elif isinstance(L[1], SlicelistObject): + if L[1].name == 'slice': + start = L[1].value[0] + end = L[1].value[1] + builder.push(ast.Slice(L[0], consts.OP_APPLY, start, end)) + else: # sliceobj (with 'step' argument) + builder.push(ast.Subscript(L[0], consts.OP_APPLY, [ast.Sliceobj(L[1].value)])) + else: + assert False, "TODO" elif len(L) == 3: if isinstance(L[1], TokenObject) and L[1].name == tok.DOT: builder.push(ast.Getattr(L[0], L[2].value)) @@ -326,11 +346,6 @@ def build_file_input(builder, nb): # FIXME: need to handle docstring ! doc = None - # doc = self.get_docstring(nodelist, symbol.file_input) - # if doc is not None: - # i = 1 - # else: - # i = 0 stmts = [] L = get_atoms(builder, nb) for node in L: @@ -343,7 +358,9 @@ continue else: stmts.append(node) - return builder.push(ast.Module(doc, ast.Stmt(stmts))) + main_stmt = ast.Stmt(stmts) + doc = get_docstring(main_stmt) + return builder.push(ast.Module(doc, main_stmt)) def build_single_input( builder, nb ): L = get_atoms( builder, nb ) @@ -394,6 +411,14 @@ elif len(L) == 3: # '(' Arglist ')' # push arglist on the stack builder.push(L[1]) + elif L[0].name == tok.LSQB: + if isinstance(L[1], SlicelistObject): + builder.push(L[1]) + else: + subs = [] + for index in range(1, len(L), 2): + subs.append(L[index]) + builder.push(SubscriptObject('subscript', subs, None)) elif len(L) == 2: # Attribute access: '.' NAME # XXX Warning: fails if trailer is used in lvalue @@ -407,7 +432,46 @@ L = get_atoms(builder, nb) builder.push(ArglistObject('arglist', parse_argument(L), None)) +def build_subscript(builder, nb): + """'.' '.' '.' | [test] ':' [test] [':' [test]] | test""" + L = get_atoms(builder, nb) + if isinstance(L[0], TokenObject) and L[0].name == tok.DOT: + # Ellipsis: + builder.push(ast.Ellipsis()) + elif len(L) == 1: + token = L[0] + if isinstance(token, TokenObject) and token.name == tok.COLON: + builder.push(SlicelistObject('slice', [None, None, None], None)) + else: + # test + builder.push(L[0]) + else: # elif len(L) > 1: + items = [] + sliceinfos = [None, None, None] + infosindex = 0 + subscript_type = 'subscript' + for token in L: + if isinstance(token, TokenObject): + if token.name == tok.COLON: + infosindex += 1 + subscript_type = 'slice' + # elif token.name == tok.COMMA: + # subscript_type = 'subscript' + else: + items.append(token) + sliceinfos[infosindex] = token + else: + items.append(token) + sliceinfos[infosindex] = token + if subscript_type == 'slice': + if infosindex == 2: + builder.push(SlicelistObject('sliceobj', sliceinfos, None)) + else: + builder.push(SlicelistObject('slice', sliceinfos, None)) + else: + builder.push(SubscriptObject('subscript', items, None)) + def build_listmaker(builder, nb): """listmaker: test ( list_for | (',' test)* [','] )""" L = get_atoms(builder, nb) @@ -440,8 +504,9 @@ funcname = L[1].value arglist = L[2] code = L[-1] + doc = get_docstring(code) # FIXME: decorators and docstring ! - builder.push(ast.Function(None, funcname, names, default, flags, None, code)) + builder.push(ast.Function(None, funcname, names, default, flags, doc, code)) def build_classdef(builder, nb): @@ -461,7 +526,8 @@ for node in base.nodes: assert isinstance(node, ast.Name) basenames.append(node) - builder.push(ast.Class(classname, basenames, None, body)) + doc = get_docstring(body) + builder.push(ast.Class(classname, basenames, doc, body)) def build_suite(builder, nb): """suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT""" @@ -628,8 +694,14 @@ def build_del_stmt(builder, nb): L = get_atoms(builder, nb) - assert isinstance(L[1], ast.Name), "build_del_stmt implementation is incomplete !" - builder.push(ast.AssName(L[1].name, consts.OP_DELETE)) + builder.push(to_lvalue(L[1], consts.OP_DELETE)) +## if isinstance(L[1], ast.Name): +## builder.push(ast.AssName(L[1].name, consts.OP_DELETE)) +## elif isinstance(L[1], ast.Getattr): +## assert "TODO", "build_del_stmt implementation is incomplete !" +## else: +## assert "TODO", "build_del_stmt implementation is incomplete !" + def build_assert_stmt(builder, nb): """assert_stmt: 'assert' test [',' test]""" @@ -920,6 +992,27 @@ return genexpr_fors +def get_docstring(stmt): + """parses a Stmt node. + + If a docstring if found, the Discard node is **removed** + from and the docstring is returned. + + If no docstring is found, is left unchanged + and None is returned + """ + if not isinstance(stmt, ast.Stmt): + return None + doc = None + first_child = stmt.nodes[0] + if isinstance(first_child, ast.Discard): + expr = first_child.expr + if isinstance(expr, ast.Const): + # This *is* a docstring, remove it from stmt list + del stmt.nodes[0] + doc = expr.value + return doc + ASTRULES = { # "single_input" : build_single_input, sym.atom : build_atom, @@ -946,6 +1039,7 @@ sym.varargslist : build_varargslist, sym.trailer : build_trailer, sym.arglist : build_arglist, + sym.subscript : build_subscript, sym.listmaker : build_listmaker, sym.funcdef : build_funcdef, sym.classdef : build_classdef, @@ -1029,6 +1123,39 @@ return "" % self.value +class SubscriptObject(ast.Node): + """helper class to build function's arg list""" + def __init__(self, name, value, src): + self.name = name + self.value = value + self.count = 0 + self.line = 0 # src.getline() + self.col = 0 # src.getcol() + + def __str__(self): + return "" % self.value + + def __repr__(self): + return "" % self.value + +class SlicelistObject(ast.Node): + def __init__(self, name, value, src): + self.name = name + self.value = value +## self.begin = value[0] +## self.end = value[1] +## self.step = value[2] + self.count = 0 + self.line = 0 # src.getline() + self.col = 0 # src.getcol() + + def __str__(self): + return "" % self.value + + def __repr__(self): + return "" % self.value + + class AstBuilderContext(AbstractContext): """specific context management for AstBuidler""" def __init__(self, rule_stack): Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_docstring.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_docstring.py Wed Aug 10 14:03:05 2005 @@ -0,0 +1,17 @@ +"""module docstring""" + + +"""hello + +""" + +class A: + """class doctring + + on several lines + """ + +def foo(self): + """function docstring""" + +"""world""" Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 10 14:03:05 2005 @@ -25,7 +25,10 @@ "x, y, z = 1, 2, 3", "x = 'a' 'b' 'c'", "del foo", - # "del foo[bar]", + "del foo[bar]", + "del foo.bar", + "l[0]", + "m[a,b]", ] funccalls = [ @@ -98,10 +101,18 @@ ] attraccess = [ - # 'a.b = 2', # Module(None, Stmt([Assign([AssAttr(Name('a'), 'b', 'OP_ASSIGN')], Const(2))])) + 'a.b = 2', 'x = a.b', ] +slices = [ + "l[:]", + "l[1:2]", + "l[1:]", + "l[:2]", + "l[0:1:2]", + ] + imports = [ 'import os', 'import sys, os', @@ -252,6 +263,19 @@ "def f(**kwargs): return 1", ] +docstrings = [ + '''def foo(): + """foo docstring""" + return 1 + ''', + '''def foo(): + """foo docstring""" + a = 1 + """bar""" + return a + ''' + ] + TESTS = [ expressions, comparisons, @@ -262,6 +286,7 @@ dictmakers, multiexpr, attraccess, + slices, imports, asserts, execs, @@ -274,6 +299,7 @@ one_stmt_funcdefs, if_stmts, tryexcepts, + docstrings, ] TARGET_DICT = { @@ -324,6 +350,8 @@ 'snippet_generator.py', 'snippet_exceptions.py', 'snippet_classes.py', + 'snippet_simple_class.py', + 'snippet_docstring.py' # 'snippet_2.py', # 'snippet_3.py', # 'snippet_4.py', @@ -340,7 +368,6 @@ # 'snippet_redirected_prints.py', # 'snippet_samples.py', # 'snippet_simple_assignment.py', -# 'snippet_simple_class.py', # 'snippet_simple_in_expr.py', # 'snippet_slice.py', # 'snippet_whitespaces.py', From adim at codespeak.net Wed Aug 10 14:45:24 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Wed, 10 Aug 2005 14:45:24 +0200 (CEST) Subject: [pypy-svn] r15910 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050810124524.9134D27B51@code1.codespeak.net> Author: adim Date: Wed Aug 10 14:45:22 2005 New Revision: 15910 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: make more tests pass Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Aug 10 14:45:22 2005 @@ -146,6 +146,23 @@ builder.push(ast.Getattr(L[0], L[2].value)) else: builder.push(ast.Power([L[0], L[2]])) + # FIXME: find a more general way to do this + elif isinstance(L[-1], ArglistObject): + # for an expression like 'a.b.c.append(3)', we want ['a', 'b', 'c'] + names = [] + for index in range(0, len(L)-1, 2): + names.append(L[index]) + while len(names) > 1: + left = names.pop(0) + right = names.pop(0) + assert isinstance(right, TokenObject) + names.insert(0, ast.Getattr(left, right.value)) + left = names[0] + arglist = L[-1] + assert isinstance(arglist, ArglistObject) + arguments, stararg, dstararg = arglist.value + builder.push(ast.CallFunc(left, arguments, stararg, dstararg)) + # FIXME: isinstance(L[-1], (SubscriptObject, SliceObject)) else: raise ValueError, "unexpected tokens: %s" % L @@ -1004,13 +1021,14 @@ if not isinstance(stmt, ast.Stmt): return None doc = None - first_child = stmt.nodes[0] - if isinstance(first_child, ast.Discard): - expr = first_child.expr - if isinstance(expr, ast.Const): - # This *is* a docstring, remove it from stmt list - del stmt.nodes[0] - doc = expr.value + if len(stmt.nodes): + first_child = stmt.nodes[0] + if isinstance(first_child, ast.Discard): + expr = first_child.expr + if isinstance(expr, ast.Const): + # This *is* a docstring, remove it from stmt list + del stmt.nodes[0] + doc = expr.value return doc ASTRULES = { Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 10 14:45:22 2005 @@ -38,6 +38,8 @@ "l = func(10, 12, a, b=c, **kwargs)", "l = func(10, 12, a, b=c, *args, **kwargs)", "l = func(10, 12, a, b=c)", + "e = l.pop(3)", + "e = k.l.pop(3)", ] listmakers = [ @@ -351,26 +353,26 @@ 'snippet_exceptions.py', 'snippet_classes.py', 'snippet_simple_class.py', - 'snippet_docstring.py' -# 'snippet_2.py', -# 'snippet_3.py', -# 'snippet_4.py', -# 'snippet_comment.py', -# 'snippet_encoding_declaration2.py', -# 'snippet_encoding_declaration3.py', -# 'snippet_encoding_declaration.py', -# 'snippet_function_calls.py', -# 'snippet_import_statements.py', -# 'snippet_list_comps.py', -# 'snippet_multiline.py', -# 'snippet_numbers.py', -# 'snippet_only_one_comment.py', -# 'snippet_redirected_prints.py', + 'snippet_docstring.py', + 'snippet_2.py', + 'snippet_3.py', + 'snippet_4.py', + 'snippet_comment.py', + 'snippet_encoding_declaration2.py', + 'snippet_encoding_declaration3.py', + 'snippet_encoding_declaration.py', + 'snippet_function_calls.py', + 'snippet_import_statements.py', + 'snippet_list_comps.py', + 'snippet_multiline.py', + 'snippet_numbers.py', + 'snippet_only_one_comment.py', + 'snippet_redirected_prints.py', + 'snippet_simple_assignment.py', + 'snippet_simple_in_expr.py', + 'snippet_slice.py', + 'snippet_whitespaces.py', # 'snippet_samples.py', -# 'snippet_simple_assignment.py', -# 'snippet_simple_in_expr.py', -# 'snippet_slice.py', -# 'snippet_whitespaces.py', ] def test_snippets(): From nik at codespeak.net Wed Aug 10 15:13:42 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 10 Aug 2005 15:13:42 +0200 (CEST) Subject: [pypy-svn] r15911 - pypy/dist/pypy/module/_sre/test Message-ID: <20050810131342.CE9F227B55@code1.codespeak.net> Author: nik Date: Wed Aug 10 15:13:36 2005 New Revision: 15911 Added: pypy/dist/pypy/module/_sre/test/ (props changed) pypy/dist/pypy/module/_sre/test/support_test_app_sre.py (contents, props changed) pypy/dist/pypy/module/_sre/test/test_app_sre.py (contents, props changed) Log: converted my unittest suite to py.test AppTests. this was harder than expected because of test fixture and helper methods. these live in support_test_app_sre now, made available to app-level test methods by a hack borrowed from test_sysmodule. Added: pypy/dist/pypy/module/_sre/test/support_test_app_sre.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/test/support_test_app_sre.py Wed Aug 10 15:13:36 2005 @@ -0,0 +1,32 @@ +"""Support functions for app-level _sre tests.""" +import locale, _sre +from sre_constants import OPCODES, ATCODES, CHCODES + +def encode_literal(string): + opcodes = [] + for character in string: + opcodes.extend([OPCODES["literal"], ord(character)]) + return opcodes + +def assert_match(opcodes, strings): + assert_something_about_match(lambda x: x, opcodes, strings) + +def assert_no_match(opcodes, strings): + assert_something_about_match(lambda x: not x, opcodes, strings) + +def assert_something_about_match(assert_modifier, opcodes, strings): + if isinstance(strings, str): + strings = [strings] + for string in strings: + assert assert_modifier(search(opcodes, string)) + +def search(opcodes, string): + pattern = _sre.compile("ignore", 0, opcodes, 0, {}, None) + return pattern.search(string) + +def void_locale(): + locale.setlocale(locale.LC_ALL, (None, None)) + +def assert_lower_equal(tests, flags): + for arg, expected in tests: + assert ord(expected) == _sre.getlower(ord(arg), flags) Added: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Wed Aug 10 15:13:36 2005 @@ -0,0 +1,885 @@ +"""Regular expression tests specific to _sre.py and accumulated during TDD. +XXX some tests are disabled because they fail on faked _sre. These should be +reenabled once we don't fake anymore by default.""" +from py.test import raises +from pypy.interpreter.gateway import app2interp_temp + +def app_init_globals_hack(): + import __builtin__ as b + import sys, os.path + # Uh-oh, ugly hack + test_path = os.path.join( + os.path.dirname(sys.modules["sys"].__file__), "../_sre/test") + sys.path.insert(0, test_path) + import support_test_app_sre + b.s = support_test_app_sre + sys.path.pop(0) + + +class AppTestSrePy: + + def test_magic(self): + import _sre, sre_constants + assert sre_constants.MAGIC == _sre.MAGIC + + def test_codesize(self): + import _sre + assert _sre.getcodesize() == _sre.CODESIZE + + +class AppTestSrePattern: + + def test_copy(self): + # copy support is disabled by default in _sre.c + import re + p = re.compile("b") + raises(TypeError, p.__copy__) + raises(TypeError, p.__deepcopy__) + + def DONOTtest_creation_attributes(self): + # XXX fails with faked _sre + import re + pattern_string = "(b)l(?Pa)" + p = re.compile(pattern_string, re.I | re.M) + assert pattern_string == p.pattern + assert re.I | re.M == p.flags + assert 2 == p.groups + assert {"g": 2} == p.groupindex + + def test_match_none(self): + import re + p = re.compile("bla") + none_matches = ["b", "bl", "blub", "jupidu"] + for string in none_matches: + assert None == p.match(string) + + def test_pos_endpos(self): + import re + # XXX maybe fancier tests here + p = re.compile("bl(a)") + tests = [("abla", 0, 4), ("abla", 1, 4), ("ablaa", 1, 4)] + for string, pos, endpos in tests: + assert p.search(string, pos, endpos) + tests = [("abla", 0, 3), ("abla", 2, 4)] + for string, pos, endpos in tests: + assert not p.search(string, pos, endpos) + + def test_findall(self): + import re + assert ["b"] == re.findall("b", "bla") + assert ["a", "u"] == re.findall("b(.)", "abalbus") + assert [("a", "l"), ("u", "s")] == re.findall("b(.)(.)", "abalbus") + assert [("a", ""), ("s", "s")] == re.findall("b(a|(s))", "babs") + + def test_finditer(self): + import re + it = re.finditer("b(.)", "brabbel") + assert "br" == it.next().group(0) + assert "bb" == it.next().group(0) + raises(StopIteration, it.next) + + def test_split(self): + import re + assert ["a", "o", "u", ""] == re.split("b", "abobub") + assert ["a", "o", "ub"] == re.split("b", "abobub", 2) + assert ['', 'a', 'l', 'a', 'lla'] == re.split("b(a)", "balballa") + assert ['', 'a', None, 'l', 'u', None, 'lla'] == ( + re.split("b([ua]|(s))", "balbulla")) + + +class AppTestSreMatch: + + def test_copy(self): + import re + # copy support is disabled by default in _sre.c + m = re.match("bla", "bla") + raises(TypeError, m.__copy__) + raises(TypeError, m.__deepcopy__) + + def DONOTtest_match_attributes(self): + # XXX fails with faked _sre + import re + c = re.compile("bla") + m = c.match("blastring") + assert "blastring" == m.string + assert c == m.re + assert 0 == m.pos + assert 9 == m.endpos + assert None == m.lastindex + assert None == m.lastgroup + assert ((0, 3),) == m.regs + + def DONOTtest_match_attributes_with_groups(self): + # XXX fails with faked _sre + import re + m = re.search("a(b)(?Pc)", "aabcd") + assert 0 == m.pos + assert 5 == m.endpos + assert 2 == m.lastindex + assert "name" == m.lastgroup + assert ((1, 4), (2, 3), (3, 4)) == m.regs + + def DONOTtest_regs_overlapping_groups(self): + # XXX fails with faked _sre + import re + m = re.match("a((b)c)", "abc") + assert ((0, 3), (1, 3), (1, 2)) == m.regs + + def test_start_end_span(self): + import re + m = re.search("a((b)c)", "aabcd") + assert (1, 4) == (m.start(), m.end()) + assert (1, 4) == m.span() + assert (2, 4) == (m.start(1), m.end(1)) + assert (2, 4) == m.span(1) + assert (2, 3) == (m.start(2), m.end(2)) + assert (2, 3) == m.span(2) + raises(IndexError, m.start, 3) + raises(IndexError, m.end, 3) + raises(IndexError, m.span, 3) + raises(IndexError, m.start, -1) + + def test_groups(self): + import re + m = re.search("a((.).)", "aabcd") + assert ("ab", "a") == m.groups() + assert ("ab", "a") == m.groups(True) + m = re.search("a((\d)|(\s))", "aa1b") + assert ("1", "1", None) == m.groups() + assert ("1", "1", True) == m.groups(True) + m = re.search("a((\d)|(\s))", "a ") + assert (" ", None, " ") == m.groups() + m = re.match("(a)", "a") + assert ("a",) == m.groups() + + def test_groupdict(self): + import re + m = re.search("a((.).)", "aabcd") + assert {} == m.groupdict() + m = re.search("a((?P.).)", "aabcd") + assert {"first": "a"} == m.groupdict() + m = re.search("a((?P\d)|(?P\s))", "aa1b") + assert {"first": "1", "second": None} == m.groupdict() + assert {"first": "1", "second": True} == m.groupdict(True) + + def test_group(self): + import re + m = re.search("a((?P\d)|(?P\s))", "aa1b") + assert "a1" == m.group() + assert ("1", "1", None) == m.group(1, 2, 3) + assert ("1", None) == m.group("first", "second") + raises(IndexError, m.group, 1, 4) + + def test_expand(self): + import re + m = re.search("a(..)(?P..)", "ab1bc") + assert "b1bcbc" == m.expand(r"\1\g\2") + + def test_sub(self): + import re + assert "bbbbb" == re.sub("a", "b", "ababa") + assert ("bbbbb", 3) == re.subn("a", "b", "ababa") + assert "dddd" == re.sub("[abc]", "d", "abcd") + assert ("dddd", 3) == re.subn("[abc]", "d", "abcd") + assert "rbd\nbr\n" == re.sub("a(.)", r"b\1\n", "radar") + assert ("rbd\nbr\n", 2) == re.subn("a(.)", r"b\1\n", "radar") + assert ("bbbba", 2) == re.subn("a", "b", "ababa", 2) + + def DONOTtest_sub_callable(self): + # XXX fails with faked _sre + import re + def call_me(match): + ret = "" + for char in match.group(): + ret += chr(ord(char) + 1) + return ret + assert ("bbbbb", 3) == re.subn("a", call_me, "ababa") + + +class DONOTAppTestSreScanner: + # XXX fails with faked _sre + + def test_scanner_attributes(self): + import re + p = re.compile("bla") + s = p.scanner("blablubla") + assert p == s.pattern + + def test_scanner_match(self): + import re + p = re.compile(".").scanner("bla") + assert ("b", "l", "a") == (p.match().group(0), + p.match().group(0), p.match().group(0)) + assert None == p.match() + + def test_scanner_search(self): + import re + p = re.compile("\d").scanner("bla23c5a") + assert ("2", "3", "5") == (p.search().group(0), + p.search().group(0), p.search().group(0)) + assert None == p.search() + + def test_scanner_zero_width_match(self): + import re, sys + if sys.version_info[:2] == (2, 3): + return + p = re.compile(".*").scanner("bla") + assert ("bla", "") == (p.search().group(0), p.search().group(0)) + assert None == p.search() + + +class AppTestGetlower: + + def setup_class(cls): + # This imports support_test_sre as the global "s" + app2interp_temp(app_init_globals_hack)(cls.space) + + def setup_method(self, method): + import locale + locale.setlocale(locale.LC_ALL, (None, None)) + + def teardown_method(self, method): + import locale + locale.setlocale(locale.LC_ALL, (None, None)) + + def test_getlower_no_flags(self): + UPPER_AE = "\xc4" + s.assert_lower_equal([("a", "a"), ("A", "a"), (UPPER_AE, UPPER_AE), + (u"\u00c4", u"\u00c4"), (u"\u4444", u"\u4444")], 0) + + def test_getlower_locale(self): + import locale, sre_constants + UPPER_AE = "\xc4" + LOWER_AE = "\xe4" + UPPER_PI = u"\u03a0" + try: + locale.setlocale(locale.LC_ALL, "de_DE") + s.assert_lower_equal([("a", "a"), ("A", "a"), (UPPER_AE, LOWER_AE), + (u"\u00c4", u"\u00e4"), (UPPER_PI, UPPER_PI)], + sre_constants.SRE_FLAG_LOCALE) + except locale.Error: + # skip test + pass + + def test_getlower_unicode(self): + import sre_constants + UPPER_AE = "\xc4" + LOWER_AE = "\xe4" + UPPER_PI = u"\u03a0" + LOWER_PI = u"\u03c0" + s.assert_lower_equal([("a", "a"), ("A", "a"), (UPPER_AE, LOWER_AE), + (u"\u00c4", u"\u00e4"), (UPPER_PI, LOWER_PI), + (u"\u4444", u"\u4444")], sre_constants.SRE_FLAG_UNICODE) + + +class AppTestSimpleSearches: + + def test_search_simple_literal(self): + import re + assert re.search("bla", "bla") + assert re.search("bla", "blab") + assert not re.search("bla", "blu") + + def test_search_simple_ats(self): + import re + assert re.search("^bla", "bla") + assert re.search("^bla", "blab") + assert not re.search("^bla", "bbla") + assert re.search("bla$", "abla") + assert re.search("bla$", "bla\n") + assert not re.search("bla$", "blaa") + + def test_search_simple_boundaries(self): + import re + UPPER_PI = u"\u03a0" + assert re.search(r"bla\b", "bla") + assert re.search(r"bla\b", "bla ja") + assert re.search(r"bla\b", u"bla%s" % UPPER_PI) + assert not re.search(r"bla\b", "blano") + assert not re.search(r"bla\b", u"bla%s" % UPPER_PI, re.UNICODE) + + def test_search_simple_categories(self): + import re + LOWER_PI = u"\u03c0" + INDIAN_DIGIT = u"\u0966" + EM_SPACE = u"\u2001" + assert re.search(r"bla\d\s\w", "bla3 b") + assert re.search(r"b\d", u"b%s" % INDIAN_DIGIT, re.UNICODE) + assert not re.search(r"b\D", u"b%s" % INDIAN_DIGIT, re.UNICODE) + assert re.search(r"b\s", u"b%s" % EM_SPACE, re.UNICODE) + assert not re.search(r"b\S", u"b%s" % EM_SPACE, re.UNICODE) + assert re.search(r"b\w", u"b%s" % LOWER_PI, re.UNICODE) + assert not re.search(r"b\W", u"b%s" % LOWER_PI, re.UNICODE) + + def test_search_simple_any(self): + import re + assert re.search(r"b..a", "jboaas") + assert not re.search(r"b..a", "jbo\nas") + assert re.search(r"b..a", "jbo\nas", re.DOTALL) + + def test_search_simple_in(self): + import re + UPPER_PI = u"\u03a0" + LOWER_PI = u"\u03c0" + EM_SPACE = u"\u2001" + LINE_SEP = u"\u2028" + assert re.search(r"b[\da-z]a", "bb1a") + assert re.search(r"b[\da-z]a", "bbsa") + assert not re.search(r"b[\da-z]a", "bbSa") + assert re.search(r"b[^okd]a", "bsa") + assert not re.search(r"b[^okd]a", "bda") + assert re.search(u"b[%s%s%s]a" % (LOWER_PI, UPPER_PI, EM_SPACE), + u"b%sa" % UPPER_PI) # bigcharset + assert re.search(u"b[%s%s%s]a" % (LOWER_PI, UPPER_PI, EM_SPACE), + u"b%sa" % EM_SPACE) + assert not re.search(u"b[%s%s%s]a" % (LOWER_PI, UPPER_PI, EM_SPACE), + u"b%sa" % LINE_SEP) + + def test_search_simple_literal_ignore(self): + import re + UPPER_PI = u"\u03a0" + LOWER_PI = u"\u03c0" + assert re.search(r"ba", "ba", re.IGNORECASE) + assert re.search(r"ba", "BA", re.IGNORECASE) + assert re.search(u"b%s" % UPPER_PI, u"B%s" % LOWER_PI, + re.IGNORECASE | re.UNICODE) + + def test_search_simple_in_ignore(self): + import re + UPPER_PI = u"\u03a0" + LOWER_PI = u"\u03c0" + assert re.search(r"ba[A-C]", "bac", re.IGNORECASE) + assert re.search(r"ba[a-c]", "baB", re.IGNORECASE) + assert re.search(u"ba[%s]" % UPPER_PI, "ba%s" % LOWER_PI, + re.IGNORECASE | re.UNICODE) + assert re.search(r"ba[^A-C]", "bar", re.IGNORECASE) + assert not re.search(r"ba[^A-C]", "baA", re.IGNORECASE) + assert not re.search(r"ba[^A-C]", "baa", re.IGNORECASE) + + def test_search_simple_branch(self): + import re + assert re.search(r"a(bb|d[ef])b", "adeb") + assert re.search(r"a(bb|d[ef])b", "abbb") + + def test_search_simple_repeat_one(self): + import re + assert re.search(r"aa+", "aa") # empty tail + assert re.search(r"aa+ab", "aaaab") # backtracking + assert re.search(r"aa*ab", "aab") # empty match + assert re.search(r"a[bc]+", "abbccb") + assert "abbcb" == re.search(r"a.+b", "abbcb\nb").group() + assert "abbcb\nb" == re.search(r"a.+b", "abbcb\nb", re.DOTALL).group() + assert re.search(r"ab+c", "aBbBbBc", re.IGNORECASE) + assert not re.search(r"aa{2,3}", "aa") # string too short + assert not re.search(r"aa{2,3}b", "aab") # too few repetitions + assert not re.search(r"aa+b", "aaaac") # tail doesn't match + + def test_search_simple_min_repeat_one(self): + import re + assert re.search(r"aa+?", "aa") # empty tail + assert re.search(r"aa+?ab", "aaaab") # forward tracking + assert re.search(r"a[bc]+?", "abbccb") + assert "abb" == re.search(r"a.+?b", "abbcb\nb").group() + assert "a\nbb" == re.search(r"a.+b", "a\nbbc", re.DOTALL).group() + assert re.search(r"ab+?c", "aBbBbBc", re.IGNORECASE) + assert not re.search(r"aa+?", "a") # string too short + assert not re.search(r"aa{2,3}?b", "aab") # too few repetitions + assert not re.search(r"aa+?b", "aaaac") # tail doesn't match + assert re.match(".*?cd", "abcabcde").end(0) == 7 + + def test_search_simple_repeat_maximizing(self): + import re + assert not re.search(r"(ab){3,5}", "abab") + assert not re.search(r"(ab){3,5}", "ababa") + assert re.search(r"(ab){3,5}", "ababab") + assert re.search(r"(ab){3,5}", "abababababab").end(0) == 10 + assert "ad" == re.search(r"(a.)*", "abacad").group(1) + assert ("abcg", "cg") == ( + re.search(r"(ab(c.)*)+", "ababcecfabcg").groups()) + assert ("cg", "cg") == ( + re.search(r"(ab|(c.))+", "abcg").groups()) + assert ("ab", "cf") == ( + re.search(r"((c.)|ab)+", "cfab").groups()) + assert re.search(r".*", "") + + def test_search_simple_repeat_minimizing(self): + import re + assert not re.search(r"(ab){3,5}?", "abab") + assert re.search(r"(ab){3,5}?", "ababab") + assert re.search(r"b(a){3,5}?b", "baaaaab") + assert not re.search(r"b(a){3,5}?b", "baaaaaab") + assert re.search(r"a(b(.)+?)*", "abdbebb") + + def test_search_simple_groupref(self): + import re + UPPER_PI = u"\u03a0" + LOWER_PI = u"\u03c0" + assert re.match(r"((ab)+)c\1", "ababcabab") + assert not re.match(r"((ab)+)c\1", "ababcab") + assert not re.search(r"(a|(b))\2", "aa") + assert re.match(r"((ab)+)c\1", "aBAbcAbaB", re.IGNORECASE) + assert re.match(r"((a.)+)c\1", u"a%sca%s" % (UPPER_PI, LOWER_PI), + re.IGNORECASE | re.UNICODE) + + def test_search_simple_groupref_exists(self): + import re, sys + if not sys.version_info[:2] == (2, 3): + assert re.search(r"(<)?bla(?(1)>)", "") + assert re.search(r"(<)?bla(?(1)>)", "bla") + assert not re.match(r"(<)?bla(?(1)>)", "|u)", "blau") + + def test_search_simple_assert(self): + import re + assert re.search(r"b(?=\d\d).{3,}", "b23a") + assert not re.search(r"b(?=\d\d).{3,}", "b2aa") + assert re.search(r"b(?<=\d.)a", "2ba") + assert not re.search(r"b(?<=\d.)a", "ba") + + def test_search_simple_assert_not(self): + import re + assert re.search(r"b(? Author: cfbolz Date: Wed Aug 10 16:02:58 2005 New Revision: 15913 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/lladdress.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/simulator.py pypy/dist/pypy/rpython/memory/test/test_address.py pypy/dist/pypy/rpython/memory/test/test_simulator.py Log: removed the addr.attached stuff. now I have a block in the simulator that is dedicated to functions and other Python objects. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Wed Aug 10 16:02:58 2005 @@ -104,12 +104,12 @@ def convert_object(self, _obj, inline_to_addr, from_parent): if inline_to_addr is not None: - inline_to_addr.attached[0] = _obj + inline_to_addr.address[0] = lladdress.get_address_of_object(_obj) return inline_to_addr else: addr = self.curraddress - addr.attached[0] = _obj - self.curraddress += struct.calcsize("i") + addr.address[0] = lladdress.get_address_of_object(_obj) + self.curraddress += struct.calcsize("P") return addr class FlowGraphConstantConverter(object): Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Wed Aug 10 16:02:58 2005 @@ -79,35 +79,11 @@ convert_from = Address convert_to = Address._getintattr -# used to attach some real python object to the address: -# for SomeObjects and Functions -class _attached_accessor(_accessor): - attached_objects = [] - object_to_number = {} - - format = "i" - size = struct.calcsize("i") - - def convert_from(self, i): - try: - return self.attached_objects[i] - except IndexError: - raise ValueError, "trying to access invalid attached object" - - def convert_to(self, obj): - try: - return self.object_to_number[obj] - except KeyError: - num = len(self.attached_objects) - self.object_to_number[obj] = num - self.attached_objects.append(obj) - return num Address.signed = property(_signed_accessor) Address.unsigned = property(_unsigned_accessor) Address.char = property(_char_accessor) Address.address = property(_address_accessor) -Address.attached = property(_attached_accessor) NULL = Address() simulator = MemorySimulator() @@ -121,6 +97,12 @@ def raw_memcopy(addr1, addr2, size): simulator.memcopy(addr1.intaddress, addr2.intaddress, size) +def get_address_of_object(obj): + return Address(simulator.get_address_of_object(obj)) + +def get_py_object(address): + return simulator.get_py_object(address.intaddress) + supported_access_types = {"signed": lltype.Signed, "unsigned": lltype.Unsigned, Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Wed Aug 10 16:02:58 2005 @@ -200,7 +200,7 @@ def _getobj(self): assert isinstance(self._T, (lltype.FuncType, lltype.PyObjectType)) - return self._address.attached[0] + return lladdress.get_py_object(self._address.address[0]) _obj = property(_getobj) def __call__(self, *args): @@ -210,7 +210,7 @@ for a, ARG in zip(args, self._T.ARGS): if lltype.typeOf(a) != ARG: raise TypeError,"calling %r with wrong argument types: %r" % (self._T, args) - callb = self._address.attached[0]._callable + callb = lladdress.get_py_object(self._address.address[0])._callable if callb is None: raise RuntimeError,"calling undefined function" return callb(*args) @@ -271,7 +271,6 @@ def nullptr(T): return simulatorptr(lltype.Ptr(T), lladdress.NULL) -#XXX unify attached objects with the address space as to samuele's suggestion def functionptr(TYPE, name, **attrs): if not isinstance(TYPE, lltype.FuncType): raise TypeError, "functionptr() for FuncTypes only" @@ -280,10 +279,11 @@ except TypeError: raise TypeError("'%r' must be hashable"%attrs) addr = lladdress.raw_malloc(get_total_size(TYPE)) - addr.attached[0] = lltype._func(TYPE, _name=name, **attrs) + addr.address[0] = lladdress.get_address_of_object( + lltype._func(TYPE, _name=name, **attrs)) return simulatorptr(lltype.Ptr(TYPE), addr) def pyobjectptr(obj): addr = lladdress.raw_malloc(get_total_size(lltype.PyObject)) - addr.attached[0] = lltype._pyobject(obj) + addr.address[0] = lladdress.get_address_of_object(lltype._pyobject(obj)) return simulatorptr(lltype.Ptr(lltype.PyObject), addr) Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Wed Aug 10 16:02:58 2005 @@ -58,11 +58,40 @@ other.memory[offset2:offset2+size] = self.memory[offset1:offset1+size] other.status[offset2:offset2+size] = self.status[offset1:offset1+size] + +# block which stores functions and PyObects +class ObjectBlock(object): + def __init__(self, baseaddress, size): + self.baseaddress = baseaddress + self.size = size + self.objects_to_num = {} + self.objects = [] + + def get_py_object(self, offset): + try: + return self.objects[offset] + except IndexError: + raise MemorySimulatorError, "trying to access unknown object" + + def get_address_of_object(self, obj): + if obj in self.objects_to_num: + return self.objects_to_num[obj] + else: + assert len(self.objects) <= self.size + index = len(self.objects) + self.objects_to_num[obj] = index + self.objects.append(obj) + return index + + +SIZE_OF_OBJECT_BLOCK = 2 ** 16 # arbitraly choosen size + class MemorySimulator(object): size_of_simulated_ram = 64 * 1024 * 1024 def __init__(self, ram_size = None): - self.blocks = [] - self.freememoryaddress = 4 + self.objectblock = ObjectBlock(4, SIZE_OF_OBJECT_BLOCK) + self.blocks = [ObjectBlock(4, SIZE_OF_OBJECT_BLOCK)] + self.freememoryaddress = 4 + SIZE_OF_OBJECT_BLOCK if ram_size is not None: self.size_of_simulated_ram = ram_size @@ -115,3 +144,13 @@ offset1 = address1 - block1.baseaddress offset2 = address2 - block2.baseaddress block1.memcopy(offset1, block2, offset2, size) + + def get_py_object(self, address): + block = self.objectblock + offset = address - block.baseaddress + assert isinstance(block, ObjectBlock) + return block.get_py_object(offset) + + def get_address_of_object(self, obj): + return (self.objectblock.get_address_of_object(obj) + + self.objectblock.baseaddress) Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Wed Aug 10 16:02:58 2005 @@ -6,6 +6,7 @@ from pypy.objspace.flow import FlowObjSpace from pypy.rpython.memory.lladdress import Address, NULL from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy +from pypy.rpython.memory.lladdress import get_py_object, get_address_of_object from pypy.rpython.memory.simulator import MemorySimulatorError class TestAddressAnnotation(object): @@ -125,28 +126,28 @@ addr.char[10] = "c" assert (addr + 10).char[0] == "c" - def test_attached_pyobjects(self): + def test_pyobjects(self): def f(x): return x + 1 def g(x): return x - 1 addr = raw_malloc(100) - addr.attached[0] = f - addr.attached[1] = g - assert addr.attached[0] == f - assert addr.attached[1] == g - assert addr.attached[0](1) == 2 - assert addr.attached[1](0) == -1 + addr.address[0] = get_address_of_object(f) + addr.address[1] = get_address_of_object(g) + assert get_py_object(addr.address[0]) == f + assert get_py_object(addr.address[1]) == g + assert get_py_object(addr.address[0])(1) == 2 + assert get_py_object(addr.address[1])(0) == -1 def test_memcopy(self): def f(x): return x + 1 addr = raw_malloc(100) - addr.attached[0] = f + addr.address[0] = get_address_of_object(f) (addr + 10).signed[0] = 42 (addr + 20).char[0] = "a" addr1 = raw_malloc(100) raw_memcopy(addr, addr1, 100) - assert addr1.attached[0](0) == 1 + assert get_py_object(addr1.address[0])(0) == 1 assert (addr1 + 10).signed[0] == 42 assert (addr1 + 20).char[0] == "a" Modified: pypy/dist/pypy/rpython/memory/test/test_simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_simulator.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_simulator.py Wed Aug 10 16:02:58 2005 @@ -66,3 +66,15 @@ for i in xrange(10000000): sim.malloc(4096) py.test.raises(MemorySimulatorError, f) + + def test_object_access(self): + sim = MemorySimulator() + def f(x): + return x + 1 + def g(x): + return x + 2 + a1 = sim.get_address_of_object(f) + a2 = sim.get_address_of_object(g) + assert sim.get_py_object(a1)(1) == 2 + assert sim.get_py_object(a2)(1) == 3 + From ericvrp at codespeak.net Wed Aug 10 16:04:04 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 10 Aug 2005 16:04:04 +0200 (CEST) Subject: [pypy-svn] r15914 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050810140404.D738E27B51@code1.codespeak.net> Author: ericvrp Date: Wed Aug 10 16:04:03 2005 New Revision: 15914 Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_exception.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: * moved neg/abs overflow tests to test_exception * fixed overflow test in support.py * neg/abs with overflow probably fail because of an llvm bug (added bug 617 to llvm bug database) * fixed test that used to require --nomagic * fixed bug in opwriter whereby to many exception raising operations were reported Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Wed Aug 10 16:04:03 2005 @@ -44,7 +44,6 @@ %tmp.13 = cast int %tmp.12 to double ; [#uses=1] ret double %tmp.13 } - """) extfunctions["%ll_time_clock"] = ((), """ @@ -82,5 +81,4 @@ return: ; preds = %entry ret void } - """) Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Wed Aug 10 16:04:03 2005 @@ -72,7 +72,6 @@ store %%structtype.object* %%exception_value, %%structtype.object** %%last_exception_value ret void } - """ % locals()) @@ -98,18 +97,17 @@ """ % locals()) -ovf_test = """ - ;overflow test - %%cond2 = setge int %%x2, 0 - br bool %%cond2, label %%return_block, label %%block2 +int_ovf_test = """ + ;integer overflow test + %cond2 = setge int %x, 0 + br bool %cond2, label %return_block, label %block2 block2: - %%tmp = sub int 0, %%x2 - %%cond3 = setne int %%x2, %%tmp - br bool %%cond3, label %%return_block, label %%ovf + %xneg = sub int 0, %x + %cond3 = setne int %x, %xneg + br bool %cond3, label %return_block, label %ovf ovf: - call fastcc void %%__prepare_OverflowError() + call fastcc void %__prepare_OverflowError() unwind - """ #unary with OverflowError only @@ -118,11 +116,10 @@ fastcc int %%int_neg_ovf(int %%x) { block1: %%x2 = sub int 0, %%x - %(ovf_test)s + %(int_ovf_test)s return_block: ret int %%x2 } - """ % locals()) extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """ @@ -132,12 +129,11 @@ br bool %%cond1, label %%return_block, label %%block1 block1: %%x2 = sub int 0, %%x - %(ovf_test)s + %(int_ovf_test)s return_block: %%result = phi int [%%x, %%block0], [%%x2, %%block1], [%%x2, %%block2] ret int %%result } - """ % locals()) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 10 16:04:03 2005 @@ -274,10 +274,12 @@ opname = op.opname.split(':',1)[1] op_args = ['%' + opname] + op_args functionref = op_args[0] - ExternalFuncNode.used_external_functions[functionref] = True - msg = "exception raising operation %s not found" %(op.opname,) - self.codewriter.comment('XXX: Error: ' + msg) - #assert functionref in extfunctions, msg + if functionref in extfunctions: + ExternalFuncNode.used_external_functions[functionref] = True + else: + msg = "exception raising operation %s not found" %(op.opname,) + self.codewriter.comment('XXX: Error: ' + msg) + #assert functionref in extfunctions, msg assert len(op_args) >= 1 assert len(self.block.exits) >= 2 #at least one label and one exception label Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Wed Aug 10 16:04:03 2005 @@ -2,7 +2,7 @@ from pypy.translator.llvm2.genllvm import compile_function from pypy.translator.test.snippet import try_raise_choose -from pypy.rpython.rarithmetic import r_uint +from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift import sys @@ -139,10 +139,10 @@ assert f(i) == zerodivrem_uint(i) def test_neg_int_ovf(): - py.test.skip("When does int_neg_ovf get generated") + py.test.skip("test failing probably because llvm things x != -x is always true") def neg_int_ovf(n): try: - r=-n + r=ovfcheck(-n) except OverflowError: return 123 return r @@ -151,14 +151,14 @@ assert f(i) == neg_int_ovf(i) def test_abs_int_ovf(): - py.test.skip("When does int_abs_ovf get generated") + py.test.skip("test failing probably because llvm things x != -x is always true") def abs_int_ovf(n): try: - r=abs(n) + r=ovfcheck(abs(n)) except OverflowError: return 123 return r - f = compile_function(abs_int_ovf, [int], True) + f = compile_function(abs_int_ovf, [int]) for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): assert f(i) == abs_int_ovf(i) @@ -263,7 +263,6 @@ assert f(i) == i def test_raise_outside_testfn(): - py.test.skip("Test needs --nomagic!") def raiser(n): if n < 0: raise ValueError("hello") @@ -281,8 +280,23 @@ except Exception: return 2 return 0 - - f = compile_function(testfn, [int]) - assert f(1) == testfn(1) - assert f(-1) == testfn(-1) + saved = no_magic() + try: + f = compile_function(testfn, [int]) + assert f(1) == testfn(1) + assert f(-1) == testfn(-1) + 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) Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Wed Aug 10 16:04:03 2005 @@ -302,14 +302,6 @@ fn = compile_function(snippet.lshift_func, [int]) raises(ValueError, fn, -1) -def test_int_unary_ovf(): - py.test.skip("int_neg_ovf operation missing (raises)") - fn = compile_function(snippet.unary_func, [int]) - for i in range(-3,3): - assert fn(i) == (-(i), abs(i-1)) - raises (OverflowError, fn, -sys.maxint-1) - raises (OverflowError, fn, -sys.maxint) - def test_uint_arith(): py.test.skip("uint_floordiv_zer operation missing (raises)") def fn(i): From ericvrp at codespeak.net Wed Aug 10 16:05:25 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 10 Aug 2005 16:05:25 +0200 (CEST) Subject: [pypy-svn] r15915 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050810140525.30D3B27B51@code1.codespeak.net> Author: ericvrp Date: Wed Aug 10 16:05:24 2005 New Revision: 15915 Modified: pypy/dist/pypy/translator/llvm2/opwriter.py Log: * removed out-of-date comments Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 10 16:05:24 2005 @@ -209,14 +209,6 @@ self.codewriter.cast(targetvar, fromtype, fromvar, targettype) same_as = cast_primitive - #cast_bool_to_char = cast_bool_to_int = cast_bool_to_uint = cast_bool_to_float = cast_bool_to_unichar = cast_primitive - #cast_char_to_bool = cast_char_to_int = cast_char_to_uint = cast_char_to_float = cast_char_to_unichar = cast_primitive - #cast_int_to_bool = cast_int_to_char = cast_int_to_uint = cast_int_to_float = cast_int_to_unichar = cast_primitive - #cast_uint_to_bool = cast_uint_to_char = cast_uint_to_int = cast_uint_to_float = cast_uint_to_unichar = cast_primitive - #cast_float_to_bool = cast_float_to_char= cast_float_to_int = cast_float_to_uint = cast_float_to_unichar = cast_primitive - #cast_unichar_to_bool=cast_unichar_to_char=cast_unichar_to_int=cast_unichar_to_uint=cast_unichar_to_float= cast_primitive - #cast_pointer = cast_primitive - def int_is_true(self, op): self.codewriter.binaryop("setne", self.db.repr_arg(op.result), From pedronis at codespeak.net Wed Aug 10 16:19:07 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 16:19:07 +0200 (CEST) Subject: [pypy-svn] r15916 - in pypy/dist/pypy: annotation objspace/flow objspace/std Message-ID: <20050810141907.9917127B51@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 16:19:04 2005 New Revision: 15916 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/objspace/flow/objspace.py pypy/dist/pypy/objspace/std/floatobject.py Log: - removing the only place that would have needed float_div_zer - pow with floats can result in an overflow error because internally is like math.pow Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Wed Aug 10 16:19:04 2005 @@ -331,6 +331,7 @@ def pow((flt1, flt2), obj3): return SomeFloat() + pow.can_only_throw = [ZeroDivisionError, ValueError, OverflowError] class __extend__(pairtype(SomeList, SomeList)): Modified: pypy/dist/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/objspace.py (original) +++ pypy/dist/pypy/objspace/flow/objspace.py Wed Aug 10 16:19:04 2005 @@ -476,6 +476,8 @@ inplace_lshift""", OverflowError) # without a _ovf version _add_except_ovf("""neg abs add sub mul floordiv div mod pow lshift""") # with a _ovf version +_add_exceptions("""pow""", + OverflowError) # for the float case del _add_exceptions, _add_except_ovf def extract_cell_content(c): Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Wed Aug 10 16:19:04 2005 @@ -193,10 +193,10 @@ def div__Float_Float(space, w_float1, w_float2): x = w_float1.floatval y = w_float2.floatval + if y == 0.0: + raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float division")) try: z = x / y - except ZeroDivisionError: - raise OperationError(space.w_ZeroDivisionError, space.wrap("float division")) except FloatingPointError: raise FailedToImplement(space.w_FloatingPointError, space.wrap("float division")) # no overflow @@ -219,7 +219,6 @@ if y == 0.0: raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float modulo")) try: - # this is a hack!!!! must be replaced by a real fmod function mod = math.fmod(x, y) if (mod and ((y < 0.0) != (mod < 0.0))): mod += y @@ -234,7 +233,6 @@ if y == 0.0: raise FailedToImplement(space.w_ZeroDivisionError, space.wrap("float modulo")) try: - # XXX this is a hack!!!! must be replaced by a real fmod function 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 From cfbolz at codespeak.net Wed Aug 10 16:23:41 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 10 Aug 2005 16:23:41 +0200 (CEST) Subject: [pypy-svn] r15917 - pypy/dist/pypy/rpython/memory Message-ID: <20050810142341.BEC3127B51@code1.codespeak.net> Author: cfbolz Date: Wed Aug 10 16:23:40 2005 New Revision: 15917 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: oops. this indirection is of course no longer needed (thanks samuele). Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Wed Aug 10 16:23:40 2005 @@ -278,12 +278,10 @@ hash(tuple(attrs.items())) except TypeError: raise TypeError("'%r' must be hashable"%attrs) - addr = lladdress.raw_malloc(get_total_size(TYPE)) - addr.address[0] = lladdress.get_address_of_object( + addr = lladdress.get_address_of_object( lltype._func(TYPE, _name=name, **attrs)) return simulatorptr(lltype.Ptr(TYPE), addr) def pyobjectptr(obj): - addr = lladdress.raw_malloc(get_total_size(lltype.PyObject)) - addr.address[0] = lladdress.get_address_of_object(lltype._pyobject(obj)) - return simulatorptr(lltype.Ptr(lltype.PyObject), addr) + addr = lladdress.get_address_of_object(lltype._pyobject(obj)) + return simulatorptr(lltype.Ptr(lltype.PyObject), addr) From ericvrp at codespeak.net Wed Aug 10 16:25:51 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 10 Aug 2005 16:25:51 +0200 (CEST) Subject: [pypy-svn] r15918 - in pypy/dist/pypy/translator/llvm2: module test Message-ID: <20050810142551.6825027B51@code1.codespeak.net> Author: ericvrp Date: Wed Aug 10 16:25:50 2005 New Revision: 15918 Modified: pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_exception.py Log: fixed int_neg_ovf and int_abs_ovf Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Wed Aug 10 16:25:50 2005 @@ -98,13 +98,8 @@ int_ovf_test = """ - ;integer overflow test - %cond2 = setge int %x, 0 - br bool %cond2, label %return_block, label %block2 -block2: - %xneg = sub int 0, %x - %cond3 = setne int %x, %xneg - br bool %cond3, label %return_block, label %ovf + %cond2 = setne int %x, -2147483648 ;-sys.maxint-1 + br bool %cond2, label %return_block, label %ovf ovf: call fastcc void %__prepare_OverflowError() unwind @@ -131,7 +126,7 @@ %%x2 = sub int 0, %%x %(int_ovf_test)s return_block: - %%result = phi int [%%x, %%block0], [%%x2, %%block1], [%%x2, %%block2] + %%result = phi int [%%x, %%block0], [%%x2, %%block1] ret int %%result } """ % locals()) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Wed Aug 10 16:25:50 2005 @@ -139,7 +139,6 @@ assert f(i) == zerodivrem_uint(i) def test_neg_int_ovf(): - py.test.skip("test failing probably because llvm things x != -x is always true") def neg_int_ovf(n): try: r=ovfcheck(-n) @@ -151,7 +150,6 @@ assert f(i) == neg_int_ovf(i) def test_abs_int_ovf(): - py.test.skip("test failing probably because llvm things x != -x is always true") def abs_int_ovf(n): try: r=ovfcheck(abs(n)) From cfbolz at codespeak.net Wed Aug 10 16:31:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 10 Aug 2005 16:31:16 +0200 (CEST) Subject: [pypy-svn] r15919 - pypy/dist/pypy/rpython/memory Message-ID: <20050810143116.EECFD27B51@code1.codespeak.net> Author: cfbolz Date: Wed Aug 10 16:31:15 2005 New Revision: 15919 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: ouch. always test before you checkin. more places that needed changing. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Wed Aug 10 16:31:15 2005 @@ -104,13 +104,9 @@ def convert_object(self, _obj, inline_to_addr, from_parent): if inline_to_addr is not None: - inline_to_addr.address[0] = lladdress.get_address_of_object(_obj) - return inline_to_addr + assert 0, "can't inline function or pyobject" else: - addr = self.curraddress - addr.address[0] = lladdress.get_address_of_object(_obj) - self.curraddress += struct.calcsize("P") - return addr + return lladdress.get_address_of_object(_obj) class FlowGraphConstantConverter(object): def __init__(self, flowgraphs): Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Wed Aug 10 16:31:15 2005 @@ -200,7 +200,7 @@ def _getobj(self): assert isinstance(self._T, (lltype.FuncType, lltype.PyObjectType)) - return lladdress.get_py_object(self._address.address[0]) + return lladdress.get_py_object(self._address) _obj = property(_getobj) def __call__(self, *args): @@ -210,7 +210,7 @@ for a, ARG in zip(args, self._T.ARGS): if lltype.typeOf(a) != ARG: raise TypeError,"calling %r with wrong argument types: %r" % (self._T, args) - callb = lladdress.get_py_object(self._address.address[0])._callable + callb = lladdress.get_py_object(self._address)._callable if callb is None: raise RuntimeError,"calling undefined function" return callb(*args) From pedronis at codespeak.net Wed Aug 10 17:17:48 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 17:17:48 +0200 (CEST) Subject: [pypy-svn] r15922 - in pypy/dist/pypy: lib module/__builtin__ objspace/std/test rpython translator Message-ID: <20050810151748.49C2327B53@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 17:17:41 2005 New Revision: 15922 Modified: pypy/dist/pypy/lib/_formatting.py pypy/dist/pypy/module/__builtin__/special.py pypy/dist/pypy/objspace/std/test/test_stringformat.py pypy/dist/pypy/rpython/rarithmetic.py pypy/dist/pypy/translator/geninterplevel.py Log: fix for test_str/userstring/format failures with tests bump geninterp number because _formatting is an indirect import Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Wed Aug 10 17:17:41 2005 @@ -242,9 +242,8 @@ return self.numeric_postprocess(r, sign) def _formatd(self, kind, v): - fmt = '%' + (self.flags.f_alt and '#' or '') + '.' + str(self.prec) + kind import __builtin__ - return __builtin__._formatd(fmt, v) + return __builtin__._formatd(self.flags.f_alt, self.prec, kind, v) class FloatFFormatter(FloatFormatter): def _format(self, v): Modified: pypy/dist/pypy/module/__builtin__/special.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/special.py (original) +++ pypy/dist/pypy/module/__builtin__/special.py Wed Aug 10 17:17:41 2005 @@ -1,4 +1,5 @@ from pypy.interpreter import gateway +from pypy.interpreter.error import OperationError from pypy.rpython import rarithmetic def _isfake(space, w_obj): @@ -6,6 +7,18 @@ #return space.wrap(bool(getattr(w_obj.typedef, 'fakedcpytype', None))) -def _formatd(space, fmt, x): +def _formatd(space, alt, prec, kind, x): + formatd_max_length = rarithmetic.formatd_max_length + if ((kind == 'g' and formatd_max_length <= 10+prec) or + (kind == 'f' and formatd_max_length <= 53+prec)): + raise OperationError(space.w_OverflowError, + space.wrap("formatted float is too long (precision too large?)")) + if alt: + alt = '#' + else: + alt = '' + + fmt = "%%%s.%d%s" % (alt, prec, kind) + return space.wrap(rarithmetic.formatd(fmt, x)) -_formatd.unwrap_spec = [gateway.ObjSpace, str, float] +_formatd.unwrap_spec = [gateway.ObjSpace, int, int, str, float] Modified: pypy/dist/pypy/objspace/std/test/test_stringformat.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_stringformat.py (original) +++ pypy/dist/pypy/objspace/std/test/test_stringformat.py Wed Aug 10 17:17:41 2005 @@ -156,3 +156,9 @@ assert "%*.*s"%( 5, 3, 'abc') == ' abc' assert "%*.*s"%( 5, 3, 'abcde') == ' abc' assert "%*.*s"%(-5, 3, 'abcde') == 'abc ' + + def test_too_long(self): + def f(fmt, x): + return fmt % x + raises(OverflowError, f, "%.70f", 2.0) + raises(OverflowError, f, "%.110g", 2.0) Modified: pypy/dist/pypy/rpython/rarithmetic.py ============================================================================== --- pypy/dist/pypy/rpython/rarithmetic.py (original) +++ pypy/dist/pypy/rpython/rarithmetic.py Wed Aug 10 17:17:41 2005 @@ -379,5 +379,7 @@ # float -> string +formatd_max_length = 120 + def formatd(fmt, x): return fmt % (x,) Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Wed Aug 10 17:17:41 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.10' # bump this for substantial changes +GI_VERSION = '1.1.11' # bump this for substantial changes # ____________________________________________________________ try: From ericvrp at codespeak.net Wed Aug 10 18:12:10 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 10 Aug 2005 18:12:10 +0200 (CEST) Subject: [pypy-svn] r15927 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050810161210.75F3727B52@code1.codespeak.net> Author: ericvrp Date: Wed Aug 10 18:12:08 2005 New Revision: 15927 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py Log: made most functions and data internal linkage Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Wed Aug 10 18:12:08 2005 @@ -36,7 +36,7 @@ self.append(" %s:" % name) def globalinstance(self, name, typeandata): - self.append("%s = global %s" % (name, typeandata)) + self.append("%s = internal global %s" % (name, typeandata)) def structdef(self, name, typereprs): self.append("%s = type { %s }" %(name, ", ".join(typereprs))) @@ -70,9 +70,13 @@ self.indent("switch %s %s, label %%%s [%s ]" % (intty, cond, defaultdest, labels)) - def openfunc(self, decl): + def openfunc(self, decl, is_entrynode=False): self.newline() - self.append("fastcc %s {" % (decl,)) + if is_entrynode: + linkage_type = '' + else: + linkage_type = 'internal ' + self.append("%sfastcc %s {" % (linkage_type, decl,)) def closefunc(self): self.append("}") Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Wed Aug 10 18:12:08 2005 @@ -257,8 +257,9 @@ # Always add type (it is safe) self.prepare_repr_arg_type(type_) - def setup_all(self): + def setup_all(self, entrynode): # Constants setup need to be done after the rest + self.entrynode = entrynode while self._pendingsetup: node = self._pendingsetup.pop() log.settingup(node) Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Wed Aug 10 18:12:08 2005 @@ -68,7 +68,7 @@ def writeimpl(self, codewriter): graph = self.graph log.writeimpl(graph.name) - codewriter.openfunc(self.getdecl()) + codewriter.openfunc(self.getdecl(), self is self.db.entrynode) nextblock = graph.startblock args = graph.startblock.inputargs l = [x for x in flatten(graph) if isinstance(x, Block)] Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Wed Aug 10 18:12:08 2005 @@ -59,7 +59,7 @@ if self.debug: print 'gen_llvm_source db.setup_all) ' + time.ctime() #7 minutes - self.db.setup_all() + self.db.setup_all(self.db.obj2node[c]) if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) #3 seconds Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Wed Aug 10 18:12:08 2005 @@ -13,23 +13,23 @@ gc_boehm = """declare ccc sbyte* %GC_malloc(uint) declare ccc sbyte* %GC_malloc_atomic(uint) -fastcc sbyte* %gc_malloc(uint %n) { +internal fastcc sbyte* %gc_malloc(uint %n) { %ptr = call ccc sbyte* %GC_malloc(uint %n) ret sbyte* %ptr } -fastcc sbyte* %gc_malloc_atomic(uint %n) { +internal fastcc sbyte* %gc_malloc_atomic(uint %n) { %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) ret sbyte* %ptr } """ -gc_disabled = """fastcc sbyte* %gc_malloc(uint %n) { +gc_disabled = """internal fastcc sbyte* %gc_malloc(uint %n) { %ptr = malloc sbyte, uint %n ret sbyte* %ptr } -fastcc sbyte* %gc_malloc_atomic(uint %n) { +internal fastcc sbyte* %gc_malloc_atomic(uint %n) { %ptr = malloc sbyte, uint %n ret sbyte* %ptr } Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Wed Aug 10 18:12:08 2005 @@ -30,7 +30,7 @@ ] simple_function_template = """ -fastcc double %%ll_math_%(function)s(%(params)s) { +internal fastcc double %%ll_math_%(function)s(%(params)s) { %%t = call ccc double %%%(function)s(%(params)s) ret double %%t } Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Wed Aug 10 18:12:08 2005 @@ -13,7 +13,7 @@ extfunctions = {} extfunctions["%ll_os_dup"] = ((), """ -fastcc int %ll_os_dup(int %fd) { +internal fastcc int %ll_os_dup(int %fd) { %ret = call ccc int %dup(int %fd) ret int %ret } @@ -21,7 +21,7 @@ """) extfunctions["%ll_os_close"] = ((), """ -fastcc void %ll_os_close(int %fd) { +internal fastcc void %ll_os_close(int %fd) { call ccc void %close(int %fd) ret void } @@ -29,7 +29,7 @@ """) extfunctions["%ll_os_open"] = (("%cast",), """ -fastcc int %ll_os_open(%structtype.rpy_string* %structstring, int %flag, int %mode) { +internal fastcc int %ll_os_open(%structtype.rpy_string* %structstring, int %flag, int %mode) { %dest = call fastcc sbyte* %cast(%structtype.rpy_string* %structstring) %fd = call ccc int %open(sbyte* %dest, int %flag, int %mode) ret int %fd @@ -38,7 +38,7 @@ """) extfunctions["%ll_os_write"] = (("%cast",), """ -fastcc int %ll_os_write(int %fd, %structtype.rpy_string* %structstring) { +internal fastcc int %ll_os_write(int %fd, %structtype.rpy_string* %structstring) { %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr %dest = call fastcc sbyte* %cast(%structtype.rpy_string* %structstring) @@ -49,7 +49,7 @@ """) extfunctions["%ll_read_into"] = ((), """ -fastcc int %ll_read_into(int %fd, %structtype.rpy_string* %structstring) { +internal fastcc int %ll_read_into(int %fd, %structtype.rpy_string* %structstring) { %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr @@ -63,7 +63,7 @@ """) extfunctions["%ll_os_isatty"] = ((), """ -fastcc bool %ll_os_isatty(int %fd) { +internal fastcc bool %ll_os_isatty(int %fd) { %ret = call ccc int %isatty(int %fd) %ret.bool = cast int %ret to bool ret bool %ret.bool @@ -72,7 +72,7 @@ """) extfunctions["%ll_os_fstat"] = ((), """ -%structtype.tuple10* %ll_os_fstat(int %fd) { +internal fastcc %structtype.tuple10* %ll_os_fstat(int %fd) { %st = alloca int, uint 32 %error = call ccc int %fstat(int %fd, int* %st) ;TODO XXX if error: raise exception Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Wed Aug 10 18:12:08 2005 @@ -19,7 +19,7 @@ extfunctions["%ll_time_time"] = ((), """ -fastcc double %ll_time_time() { +internal fastcc double %ll_time_time() { %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] %secs = alloca int ; [#uses=2] %tmp.0 = call int %gettimeofday( %struct.timeval* %t, %struct.timeval* null ) ; [#uses=1] @@ -47,7 +47,7 @@ """) extfunctions["%ll_time_clock"] = ((), """ -fastcc double %ll_time_clock() { +internal fastcc double %ll_time_clock() { entry: %tmp.0 = call int %clock( ) ; [#uses=1] %tmp.1 = cast int %tmp.0 to double ; [#uses=1] @@ -57,7 +57,7 @@ """) extfunctions["%ll_time_sleep"] = ((), """ -fastcc void %ll_time_sleep(double %secs) { +internal fastcc void %ll_time_sleep(double %secs) { entry: %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] %tmp.0 = call double %fmod( double %secs, double 1.000000e+00 ) ; [#uses=1] Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Wed Aug 10 18:12:08 2005 @@ -7,7 +7,7 @@ extfunctions = {} extfunctions["%cast"] = ((), """ -fastcc sbyte* %cast(%structtype.rpy_string* %structstring) { +internal fastcc sbyte* %cast(%structtype.rpy_string* %structstring) { %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr %length = add int %reallength, 1 @@ -31,7 +31,7 @@ #abs functions extfunctions["%int_abs"] = ((), """ -fastcc int %int_abs(int %x) { +internal fastcc int %int_abs(int %x) { block0: %cond1 = setge int %x, 0 br bool %cond1, label %return_block, label %block1 @@ -46,7 +46,7 @@ """) extfunctions["%float_abs"] = ((), """ -fastcc double %float_abs(double %x) { +internal fastcc double %float_abs(double %x) { block0: %cond1 = setge double %x, 0.0 br bool %cond1, label %return_block, label %block1 @@ -64,7 +64,7 @@ #prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ -fastcc void %%__prepare_%(exc)s() { +internal fastcc void %%__prepare_%(exc)s() { %%exception_value = call fastcc %%structtype.object* %%instantiate_%(exc)s() %%tmp = getelementptr %%structtype.object* %%exception_value, int 0, uint 0 %%exception_type = load %%structtype.object_vtable** %%tmp @@ -80,7 +80,7 @@ func, inst = func_inst.split(':') for type_ in "int uint".split(): extfunctions["%%%(type_)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ -fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { +internal fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { ;zerodiv test %%cond = seteq %(type_)s %%y, 0 @@ -108,7 +108,7 @@ #unary with OverflowError only extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """ -fastcc int %%int_neg_ovf(int %%x) { +internal fastcc int %%int_neg_ovf(int %%x) { block1: %%x2 = sub int 0, %%x %(int_ovf_test)s @@ -118,7 +118,7 @@ """ % locals()) extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """ -fastcc int %%int_abs_ovf(int %%x) { +internal fastcc int %%int_abs_ovf(int %%x) { block0: %%cond1 = setge int %%x, 0 br bool %%cond1, label %%return_block, label %%block1 From pedronis at codespeak.net Wed Aug 10 18:19:25 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 18:19:25 +0200 (CEST) Subject: [pypy-svn] r15928 - pypy/dist/lib-python Message-ID: <20050810161925.6804C27B52@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 18:19:23 2005 New Revision: 15928 Modified: pypy/dist/lib-python/conftest.py Log: allow to specify usemodules in the regr test descriptions. Use it at least in not -E mode. test test_math with our own math Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 10 18:19:23 2005 @@ -270,7 +270,8 @@ class RegrTest: """ Regression Test Declaration.""" def __init__(self, basename, enabled=False, dumbtest=False, - oldstyle=False, core=False, uselibfile=False): + oldstyle=False, core=False, uselibfile=False, + usemodules = None): self.basename = basename self.enabled = enabled self.dumbtest = dumbtest @@ -279,6 +280,9 @@ # line options haven't been parsed! self._oldstyle = oldstyle self._uselibfile = uselibfile + if usemodules is None: + usemodules = [] + self._usemodules = usemodules self.core = core def oldstyle(self): @@ -289,13 +293,17 @@ return self._uselibfile or pypy_option.uselibfile uselibfile = property(uselibfile) - + def usemodules(self): + return self._usemodules + pypy_option.usemodules + usemodules = property(usemodules) def getoptions(self): l = [] for name in 'oldstyle', 'core', 'uselibfile': if getattr(self, name): l.append(name) + for name in self.usemodules: + l.append(name) return l def ismodified(self): @@ -539,7 +547,7 @@ RegrTest('test_macpath.py', enabled=True), RegrTest('test_mailbox.py', enabled=True), RegrTest('test_marshal.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_math.py', enabled=False, core=True), + RegrTest('test_math.py', enabled=False, core=True, usemodules=['math']), RegrTest('test_md5.py', enabled=False), RegrTest('test_mhlib.py', enabled=True), RegrTest('test_mimetools.py', enabled=True, core=True), @@ -849,7 +857,7 @@ if regrtest.uselibfile: pypy_options.append('--uselibfile') pypy_options.extend( - ['--usemodules=%s' % mod for mod in pypy_option.usemodules]) + ['--usemodules=%s' % mod for mod in regrtest.usemodules]) sopt = " ".join(pypy_options) if regrtest.getoutputpath(): From pedronis at codespeak.net Wed Aug 10 18:34:24 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 18:34:24 +0200 (CEST) Subject: [pypy-svn] r15930 - pypy/dist/pypy/objspace/std Message-ID: <20050810163424.0DCA827B52@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 18:34:22 2005 New Revision: 15930 Modified: pypy/dist/pypy/objspace/std/floatobject.py Log: issue91 in-progress the rest of the code seems code, but in pow we need to decide how to distribute the work between code here and the backend implementation Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Wed Aug 10 18:34:22 2005 @@ -271,6 +271,8 @@ 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! if not space.is_w(thirdArg, space.w_None): raise FailedToImplement(space.w_TypeError, space.wrap( "pow() 3rd argument not allowed unless all arguments are integers")) @@ -281,9 +283,10 @@ except OverflowError: raise FailedToImplement(space.w_OverflowError, space.wrap("float power")) except ValueError, e: - raise FailedToImplement(space.w_ValueError, space.wrap(str(e))) - except ZeroDivisionError, e: # (0.0 ** -1) - raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e))) + raise FailedToImplement(space.w_ValueError, space.wrap(str(e))) # xxx + except ZeroDivisionError, e: + raise OperationError(space.w_ZeroDivisionError, + space.wrap("0.0 cannot be raised to a negative power")) return W_FloatObject(space, z) From pedronis at codespeak.net Wed Aug 10 18:44:41 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 18:44:41 +0200 (CEST) Subject: [pypy-svn] r15931 - pypy/dist/pypy/module/math Message-ID: <20050810164441.F0B9A27B52@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 18:44:40 2005 New Revision: 15931 Modified: pypy/dist/pypy/module/math/interp_math.py Log: issue104 chatting starting from the top: start of exception handling logic in interp_math Modified: pypy/dist/pypy/module/math/interp_math.py ============================================================================== --- pypy/dist/pypy/module/math/interp_math.py (original) +++ pypy/dist/pypy/module/math/interp_math.py Wed Aug 10 18:44:40 2005 @@ -1,5 +1,6 @@ -import math +import math +from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped class State: @@ -9,7 +10,33 @@ def get(space): return space.fromcache(State) -def pow(space, x, y): +def math1(space, f, x): + try: + y = f(x) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("math range error")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("math domain error")) + return space.wrap(y) +math1._annspecialcase_ = 'specialize:arg1' + + +def math2(space, f, x, y): + try: + r = f(x, y) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("math range error")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("math domain error")) + return space.wrap(r) +math2._annspecialcase_ = 'specialize:arg1' + +def pow(space, x, y): # xxx sort out the exception semantics of this, here in the backend and in floatobject + # do we want math.pow here? """pow(x,y) Return x**y (x to the power of y). @@ -22,7 +49,7 @@ Return the hyperbolic cosine of x. """ - return space.wrap(math.cosh(x)) + return math1(space, math.cosh, x) cosh.unwrap_spec = [ObjSpace, float] def ldexp(space, x, i): @@ -36,7 +63,7 @@ Return the Euclidean distance, sqrt(x*x + y*y). """ - return space.wrap(math.hypot(x, y)) + return math2(space, math.hypot, x, y) hypot.unwrap_spec = [ObjSpace, float, float] def tan(space, x): @@ -44,7 +71,7 @@ Return the tangent of x (measured in radians). """ - return space.wrap(math.tan(x)) + return math1(space, math.tan, x) tan.unwrap_spec = [ObjSpace, float] def asin(space, x): @@ -52,7 +79,7 @@ Return the arc sine (measured in radians) of x. """ - return space.wrap(math.asin(x)) + return math1(space, math.asin, x) asin.unwrap_spec = [ObjSpace, float] def log(space, x, w_base=NoneNotWrapped): @@ -70,7 +97,7 @@ Return the absolute value of the float x. """ - return space.wrap(math.fabs(x)) + return math1(space, math.fabs, x) fabs.unwrap_spec = [ObjSpace, float] def floor(space, x): @@ -79,7 +106,7 @@ Return the floor of x as a float. This is the largest integral value <= x. """ - return space.wrap(math.floor(x)) + return math1(space, math.floor, x) floor.unwrap_spec = [ObjSpace, float] def sqrt(space, x): @@ -87,7 +114,7 @@ Return the square root of x. """ - return space.wrap(math.sqrt(x)) + return math1(space, math.sqrt, x) sqrt.unwrap_spec = [ObjSpace, float] def frexp(space, x): @@ -106,13 +133,13 @@ def degrees(space, x): """degrees(x) -> converts angle x from radians to degrees """ - return space.wrap(x * degToRad) + return space.wrap(x / degToRad) degrees.unwrap_spec = [ObjSpace, float] def log10(space, x): """log10(x) -> the base 10 logarithm of x. """ - return space.wrap(math.log10(x)) + return math1(space, math.log10, x) log10.unwrap_spec = [ObjSpace, float] def fmod(space, x, y): @@ -120,7 +147,7 @@ Return fmod(x, y), according to platform C. x % y may differ. """ - return space.wrap(math.fmod(x, y)) + return math2(space, math.fmod, x, y) fmod.unwrap_spec = [ObjSpace, float, float] def atan(space, x): @@ -128,7 +155,7 @@ Return the arc tangent (measured in radians) of x. """ - return space.wrap(math.atan(x)) + return math1(space, math.atan, x) atan.unwrap_spec = [ObjSpace, float] def ceil(space, x): @@ -137,7 +164,7 @@ Return the ceiling of x as a float. This is the smallest integral value >= x. """ - return space.wrap(math.ceil(x)) + return math1(space, math.ceil, x) ceil.unwrap_spec = [ObjSpace, float] def sinh(space, x): @@ -145,7 +172,7 @@ Return the hyperbolic sine of x. """ - return space.wrap(math.sinh(x)) + return math1(space, math.sinh, x) sinh.unwrap_spec = [ObjSpace, float] def cos(space, x): @@ -153,7 +180,7 @@ Return the cosine of x (measured in radians). """ - return space.wrap(math.cos(x)) + return math1(space, math.cos, x) cos.unwrap_spec = [ObjSpace, float] def tanh(space, x): @@ -161,13 +188,13 @@ Return the hyperbolic tangent of x. """ - return space.wrap(math.tanh(x)) + return math1(space, math.tanh, x) tanh.unwrap_spec = [ObjSpace, float] def radians(space, x): """radians(x) -> converts angle x from degrees to radians """ - return space.wrap(x / degToRad) + return space.wrap(x * degToRad) radians.unwrap_spec = [ObjSpace, float] def sin(space, x): @@ -175,7 +202,7 @@ Return the sine of x (measured in radians). """ - return space.wrap(math.sin(x)) + return math1(space, math.sin, x) sin.unwrap_spec = [ObjSpace, float] def atan2(space, y, x): @@ -184,7 +211,7 @@ Return the arc tangent (measured in radians) of y/x. Unlike atan(y/x), the signs of both x and y are considered. """ - return space.wrap(math.atan2(y, x)) + return math2(space, math.atan2, y, x) atan2.unwrap_spec = [ObjSpace, float, float] def modf(space, x): @@ -202,7 +229,7 @@ Return e raised to the power of x. """ - return space.wrap(math.exp(x)) + return math1(space, math.exp, x) exp.unwrap_spec = [ObjSpace, float] def acos(space, x): @@ -210,5 +237,5 @@ Return the arc cosine (measured in radians) of x. """ - return space.wrap(math.acos(x)) + return math1(space, math.acos, x) acos.unwrap_spec = [ObjSpace, float] From nik at codespeak.net Wed Aug 10 19:17:31 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 10 Aug 2005 19:17:31 +0200 (CEST) Subject: [pypy-svn] r15933 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050810171731.6448F27B52@code1.codespeak.net> Author: nik Date: Wed Aug 10 19:17:29 2005 New Revision: 15933 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: moved more functions from app- to interp-level. added interp-level tests. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Wed Aug 10 19:17:29 2005 @@ -21,5 +21,8 @@ '_is_digit': 'interp_sre._is_digit', '_is_space': 'interp_sre._is_space', '_is_word': 'interp_sre._is_word', + '_is_uni_word': 'interp_sre._is_uni_word', + '_is_loc_word': 'interp_sre._is_loc_word', '_is_linebreak': 'interp_sre._is_linebreak', + '_is_uni_linebreak': 'interp_sre._is_uni_linebreak', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Wed Aug 10 19:17:29 2005 @@ -1170,13 +1170,13 @@ def at_non_boundary(self, ctx): return not ctx.at_boundary(_sre._is_word) def at_loc_boundary(self, ctx): - return ctx.at_boundary(_is_loc_word) + return ctx.at_boundary(_sre._is_loc_word) def at_loc_non_boundary(self, ctx): - return not ctx.at_boundary(_is_loc_word) + return not ctx.at_boundary(_sre._is_loc_word) def at_uni_boundary(self, ctx): - return ctx.at_boundary(_is_uni_word) + return ctx.at_boundary(_sre._is_uni_word) def at_uni_non_boundary(self, ctx): - return not ctx.at_boundary(_is_uni_word) + return not ctx.at_boundary(_sre._is_uni_word) def unknown(self, ctx): return False @@ -1202,9 +1202,9 @@ def category_not_linebreak(self, ctx): return not _sre._is_linebreak(ctx.peek_char()) def category_loc_word(self, ctx): - return _is_loc_word(ctx.peek_char()) + return _sre._is_loc_word(ctx.peek_char()) def category_loc_not_word(self, ctx): - return not _is_loc_word(ctx.peek_char()) + return not _sre._is_loc_word(ctx.peek_char()) def category_uni_digit(self, ctx): return ctx.peek_char().isdigit() def category_uni_not_digit(self, ctx): @@ -1214,28 +1214,19 @@ def category_uni_not_space(self, ctx): return not ctx.peek_char().isspace() def category_uni_word(self, ctx): - return _is_uni_word(ctx.peek_char()) + return _sre._is_uni_word(ctx.peek_char()) def category_uni_not_word(self, ctx): - return not _is_uni_word(ctx.peek_char()) + return not _sre._is_uni_word(ctx.peek_char()) def category_uni_linebreak(self, ctx): - return ord(ctx.peek_char()) in _uni_linebreaks + return _sre._is_uni_linebreak(ctx.peek_char()) def category_uni_not_linebreak(self, ctx): - return ord(ctx.peek_char()) not in _uni_linebreaks + return not _sre._is_uni_linebreak(ctx.peek_char()) def unknown(self, ctx): return False _ChcodeDispatcher.build_dispatch_table(CHCODES, "") -def _is_loc_word(char): - return (not (ord(char) & ~255) and char.isalnum()) or char == '_' - -def _is_uni_word(char): - return char.isalnum() or char == '_' - -# Static list of all unicode codepoints reported by Py_UNICODE_ISLINEBREAK. -_uni_linebreaks = [10, 13, 28, 29, 30, 133, 8232, 8233] - def _log(message): if 0: print message Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Wed Aug 10 19:17:29 2005 @@ -1,6 +1,6 @@ from pypy.interpreter.baseobjspace import ObjSpace -_ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, +ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, @@ -8,19 +8,45 @@ 0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 ] -_linebreak = ord("\n") +linebreak = ord("\n") +underline = ord("_") + +# Static list of all unicode codepoints reported by Py_UNICODE_ISLINEBREAK. +# Using a dict as a poor man's set. +uni_linebreaks = {10: True, 13: True, 28: True, 29: True, 30: True, 133: True, + 8232: True, 8233: True} def _is_digit(space, w_char): code = space.int_w(space.ord(w_char)) - return space.newbool(code < 128 and _ascii_char_info[code] & 1) + return space.newbool(code < 128 and ascii_char_info[code] & 1) def _is_space(space, w_char): code = space.int_w(space.ord(w_char)) - return space.newbool(code < 128 and _ascii_char_info[code] & 2) + return space.newbool(code < 128 and ascii_char_info[code] & 2) def _is_word(space, w_char): code = space.int_w(space.ord(w_char)) - return space.newbool(code < 128 and _ascii_char_info[code] & 16) + return space.newbool(code < 128 and ascii_char_info[code] & 16) + +def _is_uni_word(space, w_char): + code = space.int_w(space.ord(w_char)) + w_unichar = space.newunicode([code]) + isalnum = space.is_true(space.call_method(w_unichar, "isalnum")) + return space.newbool(isalnum or code == underline) + +def _is_loc_word(space, w_char): + code = space.int_w(space.ord(w_char)) + if code > 255: + return space.newbool(False) + # Need to use this new w_char_not_uni from here on, because this one is + # guaranteed to be not unicode. + w_char_not_uni = space.wrap(chr(code)) + isalnum = space.is_true(space.call_method(w_char_not_uni, "isalnum")) + return space.newbool(isalnum or code == underline) def _is_linebreak(space, w_char): - return space.newbool(space.int_w(space.ord(w_char)) == _linebreak) + return space.newbool(space.int_w(space.ord(w_char)) == linebreak) + +def _is_uni_linebreak(space, w_char): + code = space.int_w(space.ord(w_char)) + return space.newbool(uni_linebreaks.has_key(code)) Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Wed Aug 10 19:17:29 2005 @@ -303,6 +303,7 @@ LOWER_PI = u"\u03c0" INDIAN_DIGIT = u"\u0966" EM_SPACE = u"\u2001" + LOWER_AE = "\xe4" assert re.search(r"bla\d\s\w", "bla3 b") assert re.search(r"b\d", u"b%s" % INDIAN_DIGIT, re.UNICODE) assert not re.search(r"b\D", u"b%s" % INDIAN_DIGIT, re.UNICODE) @@ -310,6 +311,7 @@ assert not re.search(r"b\S", u"b%s" % EM_SPACE, re.UNICODE) assert re.search(r"b\w", u"b%s" % LOWER_PI, re.UNICODE) assert not re.search(r"b\W", u"b%s" % LOWER_PI, re.UNICODE) + assert re.search(r"b\w", "b%s" % LOWER_AE, re.UNICODE) def test_search_simple_any(self): import re @@ -657,9 +659,11 @@ opcodes2 = s.encode_literal("b") \ + [s.OPCODES["category"], s.CHCODES["category_loc_not_word"], s.OPCODES["success"]] s.assert_no_match(opcodes1, "b\xFC") + s.assert_no_match(opcodes1, u"b\u00FC") s.assert_match(opcodes2, "b\xFC") locale.setlocale(locale.LC_ALL, "de_DE") s.assert_match(opcodes1, "b\xFC") + s.assert_no_match(opcodes1, u"b\u00FC") s.assert_no_match(opcodes2, "b\xFC") s.void_locale() except locale.Error: From pedronis at codespeak.net Wed Aug 10 19:30:01 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 19:30:01 +0200 (CEST) Subject: [pypy-svn] r15934 - pypy/dist/pypy/module/math Message-ID: <20050810173001.422B427B45@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 19:29:59 2005 New Revision: 15934 Modified: pypy/dist/pypy/module/math/interp_math.py Log: more exception handling, finished up to pow error semantics Modified: pypy/dist/pypy/module/math/interp_math.py ============================================================================== --- pypy/dist/pypy/module/math/interp_math.py (original) +++ pypy/dist/pypy/module/math/interp_math.py Wed Aug 10 19:29:59 2005 @@ -22,10 +22,21 @@ return space.wrap(y) math1._annspecialcase_ = 'specialize:arg1' +def math1_w(space, f, x): + try: + r = f(x) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("math range error")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("math domain error")) + return r +math1_w._annspecialcase_ = 'specialize:arg1' -def math2(space, f, x, y): +def math2(space, f, x, snd): try: - r = f(x, y) + r = f(x, snd) except OverflowError: raise OperationError(space.w_OverflowError, space.wrap("math range error")) @@ -55,7 +66,7 @@ def ldexp(space, x, i): """ldexp(x, i) -> x * (2**i) """ - return space.wrap(math.ldexp(x, i)) + return math2(space, math.ldexp, x, i) ldexp.unwrap_spec = [ObjSpace, float, int] def hypot(space, x, y): @@ -86,10 +97,12 @@ """log(x[, base]) -> the logarithm of x to the given base. If the base not specified, returns the natural logarithm (base e) of x. """ + num = math1_w(space, math.log, x) if w_base is None: - return space.wrap(math.log(x)) + return space.wrap(num) else: - return space.wrap(math.log(x) / math.log(space.float_w(w_base))) + den = math1_w(space, math.log, space.float_w(w_base)) + return space.wrap(num / den) log.unwrap_spec = [ObjSpace, float, W_Root] def fabs(space, x): @@ -124,7 +137,7 @@ m is a float and e is an int, such that x = m * 2.**e. If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0. """ - mant, expo = math.frexp(x) + mant, expo = math1_w(space, math.frexp, x) return space.newtuple([space.wrap(mant), space.wrap(expo)]) frexp.unwrap_spec = [ObjSpace, float] @@ -220,7 +233,7 @@ Return the fractional and integer parts of x. Both results carry the sign of x. The integer part is returned as a real. """ - frac, intpart = math.modf(x) + frac, intpart = math1_w(space, math.modf, x) return space.newtuple([space.wrap(frac), space.wrap(intpart)]) modf.unwrap_spec = [ObjSpace, float] From pedronis at codespeak.net Wed Aug 10 19:55:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 19:55:13 +0200 (CEST) Subject: [pypy-svn] r15936 - in pypy/dist/pypy: rpython rpython/module rpython/module/test translator/c translator/c/src translator/c/test Message-ID: <20050810175513.58D1A27B48@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 19:55:08 2005 New Revision: 15936 Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_math.py pypy/dist/pypy/rpython/module/test/test_ll_math.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_math.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: math.pow backend support Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Wed Aug 10 19:55:08 2005 @@ -100,6 +100,7 @@ declare(math.ldexp , float , 'll_math/ldexp') declare(math.modf , modfannotation, 'll_math/modf') declare(math.hypot , float , 'll_math/hypot') +declare(math.pow , float , 'll_math/pow') # the following functions all take one float, return one float # and are part of math.h Modified: pypy/dist/pypy/rpython/module/ll_math.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_math.py (original) +++ pypy/dist/pypy/rpython/module/ll_math.py Wed Aug 10 19:55:08 2005 @@ -15,6 +15,9 @@ ll_math_%(name)s.suggested_primitive = True """ % {"name": name}).compile() +def ll_math_pow(x, y): + return math.pow(x, y) +ll_math_pow.suggested_primitive = True FREXP_RESULT = lltype.GcStruct('tuple2', ('item0', lltype.Float), ('item1', lltype.Signed)) Modified: pypy/dist/pypy/rpython/module/test/test_ll_math.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_math.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_math.py Wed Aug 10 19:55:08 2005 @@ -36,3 +36,7 @@ def test_ll_math_fabs(): assert ll_math_fabs(math.pi/3) == math.fabs(math.pi/3) assert ll_math_fabs(-math.pi/3) == math.fabs(-math.pi/3) + +def test_ll_math_pow(): + assert ll_math_pow(2.0, 3.0) == math.pow(2.0, 3.0) + assert ll_math_pow(3.0, 2.0) == math.pow(3.0, 2.0) Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Wed Aug 10 19:55:08 2005 @@ -24,6 +24,7 @@ ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', ll_time.ll_time_time: 'LL_time_time', + ll_math.ll_math_pow: 'LL_math_pow', ll_math.ll_math_frexp: 'LL_math_frexp', ll_math.ll_math_atan2: 'LL_math_atan2', ll_math.ll_math_fmod : 'LL_math_fmod', Modified: pypy/dist/pypy/translator/c/src/ll_math.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_math.h (original) +++ pypy/dist/pypy/translator/c/src/ll_math.h Wed Aug 10 19:55:08 2005 @@ -11,6 +11,10 @@ /* XXX completely ignoring exceptions/error checking for now */ +double LL_math_pow(double x, double y) { + return pow(x, y); +} + RPyFREXP_RESULT* LL_math_frexp(double x) { int expo; double m = frexp(x, &expo); Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Wed Aug 10 19:55:08 2005 @@ -141,6 +141,19 @@ res = f1() assert res == os.strerror(2) +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): From pedronis at codespeak.net Wed Aug 10 19:59:21 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 19:59:21 +0200 (CEST) Subject: [pypy-svn] r15937 - pypy/dist/pypy/module/math Message-ID: <20050810175921.A99B727B48@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 19:59:20 2005 New Revision: 15937 Modified: pypy/dist/pypy/module/math/interp_math.py Log: use math.pow, ** and math.pow have slightly different errors behavior (ZeroDivisionError vs only ValueError and OverflowError) so no matter whether rpython float**float will be mostly unchecked or with the same behavior as CPython ** we likely want math.pow here Modified: pypy/dist/pypy/module/math/interp_math.py ============================================================================== --- pypy/dist/pypy/module/math/interp_math.py (original) +++ pypy/dist/pypy/module/math/interp_math.py Wed Aug 10 19:59:20 2005 @@ -46,13 +46,12 @@ return space.wrap(r) math2._annspecialcase_ = 'specialize:arg1' -def pow(space, x, y): # xxx sort out the exception semantics of this, here in the backend and in floatobject - # do we want math.pow here? +def pow(space, x, y): """pow(x,y) Return x**y (x to the power of y). """ - return space.wrap(x ** y) + return math2(space, math.pow, x, y) pow.unwrap_spec = [ObjSpace, float, float] def cosh(space, x): From pedronis at codespeak.net Wed Aug 10 21:27:17 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 10 Aug 2005 21:27:17 +0200 (CEST) Subject: [pypy-svn] r15939 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050810192717.2226C27B54@code1.codespeak.net> Author: pedronis Date: Wed Aug 10 21:27:15 2005 New Revision: 15939 Modified: pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/test/test_floatobject.py Log: issue91 in-progress put the sanity logic for pow in floatobject.py itself the backend now only needs to appropriate code to raise ValueError|OverflowError for math.* implementations (ll_math.h for genc) Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Wed Aug 10 21:27:15 2005 @@ -278,15 +278,33 @@ "pow() 3rd argument not allowed unless all arguments are integers")) x = w_float1.floatval y = w_float2.floatval - try: - z = x ** y - except OverflowError: - raise FailedToImplement(space.w_OverflowError, space.wrap("float power")) - except ValueError, e: - raise FailedToImplement(space.w_ValueError, space.wrap(str(e))) # xxx - except ZeroDivisionError, e: - raise OperationError(space.w_ZeroDivisionError, - space.wrap("0.0 cannot be raised to a negative power")) + z = 1.0 + if y == 0.0: + z = 1.0 + elif x == 0.0: + if y < 0.0: + raise FailedToImplement(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 FailedToImplement(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 FailedToImplement(space.w_OverflowError, space.wrap("float power")) + except ValueError: + raise FailedToImplement(space.w_ValueError, space.wrap("float power")) # xxx return W_FloatObject(space, z) Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_floatobject.py Wed Aug 10 21:27:15 2005 @@ -106,3 +106,23 @@ def test_getnewargs(self): assert 0.0 .__getnewargs__() == (0.0,) + + + def test_pow(self): + def pw(x, y): + return x ** y + def espeq(x, y): + return not abs(x-y) > 1e05 + raises(ZeroDivisionError, pw, 0.0, -1) + assert pw(0, 0.5) == 0.0 + assert espeq(pw(4.0, 0.5), 2.0) + assert pw(4.0, 0) == 1.0 + assert pw(-4.0, 0) == 1.0 + 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 + + + + From nik at codespeak.net Wed Aug 10 21:31:46 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 10 Aug 2005 21:31:46 +0200 (CEST) Subject: [pypy-svn] r15940 - pypy/dist/pypy/module/_sre/test Message-ID: <20050810193146.156BC27B55@code1.codespeak.net> Author: nik Date: Wed Aug 10 21:31:44 2005 New Revision: 15940 Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: skipping these tests if --usemodules=_sre is not explicitly passed. could reenable all tests again. thanks for the suggestion, samuele. Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Wed Aug 10 21:31:44 2005 @@ -1,7 +1,5 @@ -"""Regular expression tests specific to _sre.py and accumulated during TDD. -XXX some tests are disabled because they fail on faked _sre. These should be -reenabled once we don't fake anymore by default.""" -from py.test import raises +"""Regular expression tests specific to _sre.py and accumulated during TDD.""" +from py.test import raises, skip from pypy.interpreter.gateway import app2interp_temp def app_init_globals_hack(): @@ -15,9 +13,15 @@ b.s = support_test_app_sre sys.path.pop(0) +def skip_if_faked(cls): + if "_sre" not in cls.space.options.usemodules: + skip("--usemodules=_sre option not provided") + class AppTestSrePy: + setup_class = skip_if_faked + def test_magic(self): import _sre, sre_constants assert sre_constants.MAGIC == _sre.MAGIC @@ -29,6 +33,8 @@ class AppTestSrePattern: + setup_class = skip_if_faked + def test_copy(self): # copy support is disabled by default in _sre.c import re @@ -36,8 +42,7 @@ raises(TypeError, p.__copy__) raises(TypeError, p.__deepcopy__) - def DONOTtest_creation_attributes(self): - # XXX fails with faked _sre + def test_creation_attributes(self): import re pattern_string = "(b)l(?Pa)" p = re.compile(pattern_string, re.I | re.M) @@ -89,6 +94,8 @@ class AppTestSreMatch: + setup_class = skip_if_faked + def test_copy(self): import re # copy support is disabled by default in _sre.c @@ -96,8 +103,7 @@ raises(TypeError, m.__copy__) raises(TypeError, m.__deepcopy__) - def DONOTtest_match_attributes(self): - # XXX fails with faked _sre + def test_match_attributes(self): import re c = re.compile("bla") m = c.match("blastring") @@ -109,8 +115,7 @@ assert None == m.lastgroup assert ((0, 3),) == m.regs - def DONOTtest_match_attributes_with_groups(self): - # XXX fails with faked _sre + def test_match_attributes_with_groups(self): import re m = re.search("a(b)(?Pc)", "aabcd") assert 0 == m.pos @@ -119,8 +124,7 @@ assert "name" == m.lastgroup assert ((1, 4), (2, 3), (3, 4)) == m.regs - def DONOTtest_regs_overlapping_groups(self): - # XXX fails with faked _sre + def test_regs_overlapping_groups(self): import re m = re.match("a((b)c)", "abc") assert ((0, 3), (1, 3), (1, 2)) == m.regs @@ -185,8 +189,7 @@ assert ("rbd\nbr\n", 2) == re.subn("a(.)", r"b\1\n", "radar") assert ("bbbba", 2) == re.subn("a", "b", "ababa", 2) - def DONOTtest_sub_callable(self): - # XXX fails with faked _sre + def test_sub_callable(self): import re def call_me(match): ret = "" @@ -196,8 +199,9 @@ assert ("bbbbb", 3) == re.subn("a", call_me, "ababa") -class DONOTAppTestSreScanner: - # XXX fails with faked _sre +class AppTestSreScanner: + + setup_class = skip_if_faked def test_scanner_attributes(self): import re @@ -230,6 +234,8 @@ class AppTestGetlower: + setup_class = skip_if_faked + def setup_class(cls): # This imports support_test_sre as the global "s" app2interp_temp(app_init_globals_hack)(cls.space) @@ -274,6 +280,8 @@ class AppTestSimpleSearches: + setup_class = skip_if_faked + def test_search_simple_literal(self): import re assert re.search("bla", "bla") @@ -447,44 +455,43 @@ class AppTestMarksStack: + setup_class = skip_if_faked + def test_mark_stack_branch(self): import re m = re.match("b(.)a|b.b", "bob") assert None == m.group(1) - # XXX fails with faked _sre - #assert None == m.lastindex + assert None == m.lastindex def test_mark_stack_repeat_one(self): import re m = re.match("\d+1((2)|(3))4", "2212413") assert ("2", "2", None) == m.group(1, 2, 3) - # XXX fails with faked _sre - #assert 1 == m.lastindex + assert 1 == m.lastindex def test_mark_stack_min_repeat_one(self): import re m = re.match("\d+?1((2)|(3))44", "221341244") assert ("2", "2", None) == m.group(1, 2, 3) - # XXX fails with faked _sre - #assert 1 == m.lastindex + assert 1 == m.lastindex def test_mark_stack_max_until(self): import re m = re.match("(\d)+1((2)|(3))4", "2212413") assert ("2", "2", None) == m.group(2, 3, 4) - # XXX fails with faked _sre - #assert 2 == m.lastindex + assert 2 == m.lastindex def test_mark_stack_min_until(self): import re m = re.match("(\d)+?1((2)|(3))44", "221341244") assert ("2", "2", None) == m.group(2, 3, 4) - # XXX fails with faked _sre - #assert 2 == m.lastindex + assert 2 == m.lastindex class AppTestOpcodes: + setup_class = skip_if_faked + def setup_class(cls): # This imports support_test_sre as the global "s" app2interp_temp(app_init_globals_hack)(cls.space) @@ -863,6 +870,8 @@ class AppTestOptimizations: """These tests try to trigger optmized edge cases.""" + setup_class = skip_if_faked + def test_match_length_optimization(self): import re assert None == re.match("bla", "blub") From nik at codespeak.net Wed Aug 10 21:36:22 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 10 Aug 2005 21:36:22 +0200 (CEST) Subject: [pypy-svn] r15941 - pypy/dist/pypy/module/_sre/test Message-ID: <20050810193622.A5CB427B55@code1.codespeak.net> Author: nik Date: Wed Aug 10 21:36:21 2005 New Revision: 15941 Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: oops, skip fixture for some tests was wrong. Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Wed Aug 10 21:36:21 2005 @@ -234,9 +234,8 @@ class AppTestGetlower: - setup_class = skip_if_faked - def setup_class(cls): + skip_if_faked(cls) # This imports support_test_sre as the global "s" app2interp_temp(app_init_globals_hack)(cls.space) @@ -490,9 +489,8 @@ class AppTestOpcodes: - setup_class = skip_if_faked - def setup_class(cls): + skip_if_faked(cls) # This imports support_test_sre as the global "s" app2interp_temp(app_init_globals_hack)(cls.space) From nik at codespeak.net Wed Aug 10 23:05:22 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 10 Aug 2005 23:05:22 +0200 (CEST) Subject: [pypy-svn] r15943 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050810210522.D17BF27B5A@code1.codespeak.net> Author: nik Date: Wed Aug 10 23:05:20 2005 New Revision: 15943 Added: pypy/dist/pypy/module/_sre/test/autopath.py (contents, props changed) pypy/dist/pypy/module/_sre/test/test_interp_sre.py (contents, props changed) Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved whole category matching/dispatching to interp-level. added the interp-level tests (missed them some commits ago) Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Wed Aug 10 23:05:20 2005 @@ -18,11 +18,12 @@ } interpleveldefs = { - '_is_digit': 'interp_sre._is_digit', - '_is_space': 'interp_sre._is_space', - '_is_word': 'interp_sre._is_word', - '_is_uni_word': 'interp_sre._is_uni_word', - '_is_loc_word': 'interp_sre._is_loc_word', - '_is_linebreak': 'interp_sre._is_linebreak', - '_is_uni_linebreak': 'interp_sre._is_uni_linebreak', + '_category_dispatch': 'interp_sre.category_dispatch', + '_is_digit': 'interp_sre.is_digit', + '_is_space': 'interp_sre.is_space', + '_is_word': 'interp_sre.is_word', + '_is_uni_word': 'interp_sre.is_uni_word', + '_is_loc_word': 'interp_sre.is_loc_word', + '_is_linebreak': 'interp_sre.is_linebreak', + '_is_uni_linebreak': 'interp_sre.is_uni_linebreak', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Wed Aug 10 23:05:20 2005 @@ -549,7 +549,6 @@ def __init__(self): self.executing_contexts = {} self.at_dispatcher = _AtcodeDispatcher() - self.ch_dispatcher = _ChcodeDispatcher() self.set_dispatcher = _CharsetDispatcher() def match(self, context): @@ -643,7 +642,8 @@ # match at given category # #self._log(ctx, "CATEGORY", ctx.peek_code(1)) - if ctx.at_end() or not self.ch_dispatcher.dispatch(ctx.peek_code(1), ctx): + if ctx.at_end() or \ + not _sre._category_dispatch(ctx.peek_code(1), ctx.peek_char()): ctx.has_matched = False return True ctx.skip_code(2) @@ -1083,9 +1083,6 @@ class _CharsetDispatcher(_Dispatcher): - def __init__(self): - self.ch_dispatcher = _ChcodeDispatcher() - def reset(self, char): self.char = char self.ok = True @@ -1100,7 +1097,7 @@ ctx.skip_code(2) def set_category(self, ctx): # - if self.ch_dispatcher.dispatch(ctx.peek_code(1), ctx): + if _sre._category_dispatch(ctx.peek_code(1), ctx.peek_char()): return self.ok else: ctx.skip_code(2) @@ -1183,50 +1180,6 @@ _AtcodeDispatcher.build_dispatch_table(ATCODES, "") -class _ChcodeDispatcher(_Dispatcher): - - def category_digit(self, ctx): - return _sre._is_digit(ctx.peek_char()) - def category_not_digit(self, ctx): - return not _sre._is_digit(ctx.peek_char()) - def category_space(self, ctx): - return _sre._is_space(ctx.peek_char()) - def category_not_space(self, ctx): - return not _sre._is_space(ctx.peek_char()) - def category_word(self, ctx): - return _sre._is_word(ctx.peek_char()) - def category_not_word(self, ctx): - return not _sre._is_word(ctx.peek_char()) - def category_linebreak(self, ctx): - return _sre._is_linebreak(ctx.peek_char()) - def category_not_linebreak(self, ctx): - return not _sre._is_linebreak(ctx.peek_char()) - def category_loc_word(self, ctx): - return _sre._is_loc_word(ctx.peek_char()) - def category_loc_not_word(self, ctx): - return not _sre._is_loc_word(ctx.peek_char()) - def category_uni_digit(self, ctx): - return ctx.peek_char().isdigit() - def category_uni_not_digit(self, ctx): - return not ctx.peek_char().isdigit() - def category_uni_space(self, ctx): - return ctx.peek_char().isspace() - def category_uni_not_space(self, ctx): - return not ctx.peek_char().isspace() - def category_uni_word(self, ctx): - return _sre._is_uni_word(ctx.peek_char()) - def category_uni_not_word(self, ctx): - return not _sre._is_uni_word(ctx.peek_char()) - def category_uni_linebreak(self, ctx): - return _sre._is_uni_linebreak(ctx.peek_char()) - def category_uni_not_linebreak(self, ctx): - return not _sre._is_uni_linebreak(ctx.peek_char()) - def unknown(self, ctx): - return False - -_ChcodeDispatcher.build_dispatch_table(CHCODES, "") - - def _log(message): if 0: print message Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Wed Aug 10 23:05:20 2005 @@ -1,5 +1,7 @@ from pypy.interpreter.baseobjspace import ObjSpace +#### Category helpers + ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, @@ -16,25 +18,31 @@ uni_linebreaks = {10: True, 13: True, 28: True, 29: True, 30: True, 133: True, 8232: True, 8233: True} -def _is_digit(space, w_char): +def is_digit(space, w_char): code = space.int_w(space.ord(w_char)) return space.newbool(code < 128 and ascii_char_info[code] & 1) -def _is_space(space, w_char): +def is_uni_digit(space, w_char): + return space.newbool(space.is_true(space.call_method(w_char, "isdigit"))) + +def is_space(space, w_char): code = space.int_w(space.ord(w_char)) return space.newbool(code < 128 and ascii_char_info[code] & 2) -def _is_word(space, w_char): +def is_uni_space(space, w_char): + return space.newbool(space.is_true(space.call_method(w_char, "isspace"))) + +def is_word(space, w_char): code = space.int_w(space.ord(w_char)) return space.newbool(code < 128 and ascii_char_info[code] & 16) -def _is_uni_word(space, w_char): +def is_uni_word(space, w_char): code = space.int_w(space.ord(w_char)) w_unichar = space.newunicode([code]) isalnum = space.is_true(space.call_method(w_unichar, "isalnum")) return space.newbool(isalnum or code == underline) -def _is_loc_word(space, w_char): +def is_loc_word(space, w_char): code = space.int_w(space.ord(w_char)) if code > 255: return space.newbool(False) @@ -44,9 +52,34 @@ isalnum = space.is_true(space.call_method(w_char_not_uni, "isalnum")) return space.newbool(isalnum or code == underline) -def _is_linebreak(space, w_char): +def is_linebreak(space, w_char): return space.newbool(space.int_w(space.ord(w_char)) == linebreak) -def _is_uni_linebreak(space, w_char): +def is_uni_linebreak(space, w_char): code = space.int_w(space.ord(w_char)) return space.newbool(uni_linebreaks.has_key(code)) + + +#### Category dispatch + +def category_dispatch(space, w_chcode, w_char): + chcode = space.int_w(w_chcode) + if chcode >= len(category_dispatch_table): + return space.newbool(False) + w_function, negate = category_dispatch_table[chcode] + w_result = w_function(space, w_char) + if negate: + return space.newbool(not space.is_true(w_result)) + else: + return w_result + +# Maps opcodes by indices to (function, negate) tuples. +category_dispatch_table = [ + (is_digit, False), (is_digit, True), (is_space, False), + (is_space, True), (is_word, False), (is_word, True), + (is_linebreak, False), (is_linebreak, True), (is_loc_word, False), + (is_loc_word, True), (is_uni_digit, False), (is_uni_digit, True), + (is_uni_space, False), (is_uni_space, True), (is_uni_word, False), + (is_uni_word, True), (is_uni_linebreak, False), + (is_uni_linebreak, True) +] Added: pypy/dist/pypy/module/_sre/test/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/test/autopath.py Wed Aug 10 23:05:20 2005 @@ -0,0 +1,120 @@ +""" +self cloning, automatic path configuration + +copy this into any subdirectory of pypy from which scripts need +to be run, typically all of the test subdirs. +The idea is that any such script simply issues + + import autopath + +and this will make sure that the parent directory containing "pypy" +is in sys.path. + +If you modify the master "autopath.py" version (in pypy/tool/autopath.py) +you can directly run it which will copy itself on all autopath.py files +it finds under the pypy root directory. + +This module always provides these attributes: + + pypydir pypy root directory path + this_dir directory where this autopath.py resides + +""" + + +def __dirinfo(part): + """ return (partdir, this_dir) and insert parent of partdir + into sys.path. If the parent directories don't have the part + an EnvironmentError is raised.""" + + import sys, os + try: + head = this_dir = os.path.realpath(os.path.dirname(__file__)) + except NameError: + head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0])) + + while head: + partdir = head + head, tail = os.path.split(head) + if tail == part: + break + else: + raise EnvironmentError, "'%s' missing in '%r'" % (partdir, this_dir) + + checkpaths = sys.path[:] + pypy_root = os.path.join(head, '') + + while checkpaths: + orig = checkpaths.pop() + fullorig = os.path.join(os.path.realpath(orig), '') + if fullorig.startswith(pypy_root): + if os.path.exists(os.path.join(fullorig, '__init__.py')): + sys.path.remove(orig) + try: + sys.path.remove(head) + except ValueError: + pass + sys.path.insert(0, head) + + munged = {} + for name, mod in sys.modules.items(): + fn = getattr(mod, '__file__', None) + if '.' in name or not isinstance(fn, str): + continue + newname = os.path.splitext(os.path.basename(fn))[0] + if not newname.startswith(part + '.'): + continue + path = os.path.join(os.path.dirname(os.path.realpath(fn)), '') + if path.startswith(pypy_root) and newname != part: + modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep) + if newname != '__init__': + modpaths.append(newname) + modpath = '.'.join(modpaths) + if modpath not in sys.modules: + munged[modpath] = mod + + for name, mod in munged.iteritems(): + if name not in sys.modules: + sys.modules[name] = mod + if '.' in name: + prename = name[:name.rfind('.')] + postname = name[len(prename)+1:] + if prename not in sys.modules: + __import__(prename) + if not hasattr(sys.modules[prename], postname): + setattr(sys.modules[prename], postname, mod) + + return partdir, this_dir + +def __clone(): + """ clone master version of autopath.py into all subdirs """ + from os.path import join, walk + if not this_dir.endswith(join('pypy','tool')): + raise EnvironmentError("can only clone master version " + "'%s'" % join(pypydir, 'tool',_myname)) + + + def sync_walker(arg, dirname, fnames): + if _myname in fnames: + fn = join(dirname, _myname) + f = open(fn, 'rwb+') + try: + if f.read() == arg: + print "checkok", fn + else: + print "syncing", fn + f = open(fn, 'w') + f.write(arg) + finally: + f.close() + s = open(join(pypydir, 'tool', _myname), 'rb').read() + walk(pypydir, sync_walker, s) + +_myname = 'autopath.py' + +# set guaranteed attributes + +pypydir, this_dir = __dirinfo('pypy') + +if __name__ == '__main__': + __clone() Added: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Wed Aug 10 23:05:20 2005 @@ -0,0 +1,50 @@ +"""Interp-level _sre tests.""" +import autopath +from py.test import raises +import pypy.module._sre.interp_sre as isre + +EM_SPACE = u"\u2001" +INDIAN_DIGIT = u"\u0966" + +def test_is_uni_linebreak(space): + for char in ["\n", "\r"]: + assert space.is_true(isre.is_uni_linebreak(space, space.wrap(char))) + assert space.is_true(isre.is_uni_linebreak(space, space.newunicode([ord(char)]))) + for char in [" ", "b"]: + assert not space.is_true(isre.is_uni_linebreak(space, space.wrap(char))) + assert not space.is_true(isre.is_uni_linebreak(space, space.newunicode([ord(char)]))) + assert space.is_true(isre.is_uni_linebreak(space, space.newunicode([8232]))) + +def test_is_uni_word(space): + for char in ["a", "_", "\xe4"]: + assert space.is_true(isre.is_uni_word(space, space.wrap(char))) + for char in ["a", "_", "\xe4", u"\u00e4", u"\u03a0"]: + assert space.is_true(isre.is_uni_word(space, space.newunicode([ord(char)]))) + for char in [".", " "]: + assert not space.is_true(isre.is_uni_word(space, space.wrap(char))) + for char in [".", " ", EM_SPACE]: + assert not space.is_true(isre.is_uni_word(space, space.newunicode([ord(char)]))) + +def test_is_loc_word(space): + # should also test chars actually affected by locale (between 128 and 256) + for char in ["1", "2"]: + assert space.is_true(isre.is_loc_word(space, space.wrap(char))) + assert space.is_true(isre.is_loc_word(space, space.newunicode([ord(char)]))) + for char in [" ", u".", u"\u03a0"]: + assert not space.is_true(isre.is_loc_word(space, space.newunicode([ord(char)]))) + +def test_is_uni_digit(space): + for char in ["0", "9"]: + assert space.is_true(isre.is_uni_digit(space, space.wrap(char))) + for char in ["0", "9", INDIAN_DIGIT]: + assert space.is_true(isre.is_uni_digit(space, space.newunicode([ord(char)]))) + for char in [" ", "s"]: + assert not space.is_true(isre.is_uni_digit(space, space.wrap(char))) + +def test_is_uni_space(space): + for char in [" ", "\t"]: + assert space.is_true(isre.is_uni_space(space, space.wrap(char))) + for char in ["\v", "\n", EM_SPACE]: + assert space.is_true(isre.is_uni_space(space, space.newunicode([ord(char)]))) + for char in ["a", "1"]: + assert not space.is_true(isre.is_uni_space(space, space.wrap(char))) From rxe at codespeak.net Thu Aug 11 00:33:18 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 11 Aug 2005 00:33:18 +0200 (CEST) Subject: [pypy-svn] r15948 - pypy/branch/pypy-sre Message-ID: <20050810223318.4AF9D27B5A@code1.codespeak.net> Author: rxe Date: Thu Aug 11 00:33:18 2005 New Revision: 15948 Removed: pypy/branch/pypy-sre/ Log: cleanup sre testing branch from sprint. From pedronis at codespeak.net Thu Aug 11 02:09:48 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 11 Aug 2005 02:09:48 +0200 (CEST) Subject: [pypy-svn] r15949 - pypy/dist/pypy/rpython Message-ID: <20050811000948.1EC1027B5D@code1.codespeak.net> Author: pedronis Date: Thu Aug 11 02:09:46 2005 New Revision: 15949 Modified: pypy/dist/pypy/rpython/lltype.py Log: first pass at slottifying _ptr, _array and _struct memory usage after rtyping of PyPy (before backend) went from 392m to 237m. Modified: pypy/dist/pypy/rpython/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltype.py (original) +++ pypy/dist/pypy/rpython/lltype.py Thu Aug 11 02:09:46 2005 @@ -461,14 +461,32 @@ class _ptr(object): - _weak = False + __slots__ = ('_TYPE', '_T', + '_weak', '_immortal', + '_obj0', '__weakref__') + + def _set_TYPE(self, TYPE): + _ptr._TYPE.__set__(self, TYPE) + + def _set_T(self, T): + _ptr._T.__set__(self, T) + + def _set_weak(self, weak): + _ptr._weak.__set__(self, weak) + + def _set_immortal(self, immortal): + _ptr._immortal.__set__(self, immortal) + + def _set_obj0(self, obj): + _ptr._obj0.__set__(self, obj) def _needsgc(self): return self._TYPE._needsgc() # xxx other rules? def __init__(self, TYPE, pointing_to, immortal=False): - self.__dict__['_TYPE'] = TYPE - self.__dict__['_T'] = TYPE.TO + self._set_TYPE(TYPE) + self._set_T(TYPE.TO) + self._set_weak(False) self._setobj(pointing_to, immortal) def __eq__(self, other): @@ -496,10 +514,10 @@ elif immortal or isinstance(self._T, (GC_CONTAINER, FuncType)): obj0 = pointing_to else: - self.__dict__['_weak'] = True + self._set_weak(True) obj0 = weakref.ref(pointing_to) - self.__dict__['_immortal'] = immortal - self.__dict__['_obj0'] = obj0 + self._set_immortal(immortal) + self._set_obj0(obj0) def _getobj(self): obj = self._obj0 @@ -596,11 +614,20 @@ return callb(*args) raise TypeError("%r instance is not a function" % (self._T,)) +assert not '__dict__' in dir(_ptr) class _parentable(object): - _wrparent = None _kind = "?" + __slots__ = ('_TYPE', + '_parent_type', '_parent_index', '_keepparent', + '_wrparent', + '__weakref__') + + def __init__(self, TYPE): + self._wrparent = None + self._TYPE = TYPE + def _setparentstructure(self, parent, parentindex): self._wrparent = weakref.ref(parent) self._parent_type = typeOf(parent) @@ -625,12 +652,30 @@ def _check(self): self._parentstructure() + +def _struct_variety(flds, cache={}): + flds = list(flds) + flds.sort() + tag = tuple(flds) + try: + return cache[tag] + except KeyError: + class _struct1(_struct): + __slots__ = flds + cache[tag] = _struct1 + return _struct1 class _struct(_parentable): _kind = "structure" + __slots__ = () + + def __new__(self, TYPE, n=None, parent=None, parentindex=None): + my_variety = _struct_variety(TYPE._names) + return object.__new__(my_variety) + def __init__(self, TYPE, n=None, parent=None, parentindex=None): - self._TYPE = TYPE + _parentable.__init__(self, TYPE) if n is not None and TYPE._arrayfld is None: raise TypeError("%r is not variable-sized" % (TYPE,)) if n is None and TYPE._arrayfld is not None: @@ -666,12 +711,14 @@ class _array(_parentable): _kind = "array" + __slots__ = ('items',) + def __init__(self, TYPE, n, parent=None, parentindex=None): if not isinstance(n, int): raise TypeError, "array length must be an int" if n < 0: raise ValueError, "negative array length" - self._TYPE = TYPE + _parentable.__init__(self, TYPE) self.items = [TYPE.OF._defl(parent=self, parentindex=j) for j in range(n)] if parent is not None: @@ -694,6 +741,10 @@ return 'array [ %s ]' % (', '.join(['%s' % self._str_item(item) for item in self.items]),) +assert not '__dict__' in dir(_array) +assert not '__dict__' in dir(_struct) + + class _func(object): def __init__(self, TYPE, **attrs): self._TYPE = TYPE From cfbolz at codespeak.net Thu Aug 11 12:50:15 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 12:50:15 +0200 (CEST) Subject: [pypy-svn] r15957 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050811105015.A5A1727B6E@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 12:50:14 2005 New Revision: 15957 Added: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: added a simple implementation of free_non_gc_object. Added: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Aug 11 12:50:14 2005 @@ -0,0 +1,17 @@ +import struct + +class GCError(Exception): + pass + +class FREED_OBJECT(object): + def __getattribute__(self, attr): + raise GCError("trying to access freed object") + def __setattribute__(self, attr, value): + raise GCError("trying to access freed object") + + +def free_non_gc_object(obj): + assert obj.__class__._raw_allocate_ + obj.__dict__ = {} + obj.__class__ = FREED_OBJECT + Added: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Thu Aug 11 12:50:14 2005 @@ -0,0 +1,21 @@ +import py + +from pypy.rpython.memory.gc import free_non_gc_object, GCError + +def test_free_non_gc_object(): + class TestClass(object): + _raw_allocate_ = True + def __init__(self, a): + self.a = a + def method1(self): + return self.a + def method2(self): + return 42 + t = TestClass(1) + assert t.method1() == 1 + assert t.method2() == 42 + free_non_gc_object(t) + py.test.raises(GCError, "t.method1()") + py.test.raises(GCError, "t.method2()") + py.test.raises(GCError, "t.a") + From adim at codespeak.net Thu Aug 11 12:59:50 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Thu, 11 Aug 2005 12:59:50 +0200 (CEST) Subject: [pypy-svn] r15958 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050811105950.1A17327B6E@code1.codespeak.net> Author: adim Date: Thu Aug 11 12:59:47 2005 New Revision: 15958 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - improved "power:" rule reducing - fixed several bugs - all snippets files in the "samples" dir are now parsed correctly Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Thu Aug 11 12:59:47 2005 @@ -1,4 +1,7 @@ - +"""This module provides the astbuilder class which is to be used +by GrammarElements to directly build the AST during parsing +without going trhough the nested tuples step +""" from grammar import BaseGrammarBuilder, AbstractContext from pypy.interpreter.astcompiler import ast, consts @@ -6,19 +9,230 @@ import pypy.interpreter.pyparser.pysymbol as sym import pypy.interpreter.pyparser.pytoken as tok -## these tests should be methods of the ast objects DEBUG_MODE = False -def is_lvalue( ast_node ): - return True -def to_lvalue( ast_node, OP ): +### Parsing utilites ################################################# +def parse_except_clause(tokens): + """parses 'except' [test [',' test]] ':' suite + and returns a 4-tuple : (tokens_read, expr1, expr2, except_body) + """ + clause_length = 1 + # Read until end of except clause (bound by following 'else', + # or 'except' or end of tokens) + while clause_length < len(tokens): + token = tokens[clause_length] + if isinstance(token, TokenObject) and \ + (token.value == 'except' or token.value == 'else'): + break + clause_length += 1 + # if clause_length >= len(tokens): + # raise Exception + if clause_length == 3: + # case 'except: body' + return (3, None, None, tokens[2]) + elif clause_length == 4: + # case 'except Exception: body': + return (4, tokens[1], None, tokens[3]) + else: + # case 'except Exception, exc: body' + return (6, tokens[1], to_lvalue(tokens[3], consts.OP_ASSIGN), tokens[5]) + + +def parse_dotted_names(tokens): + """parses NAME('.' NAME)* and returns full dotted name + + this function doesn't assume that the list ends after the + last 'NAME' element + """ + name = tokens[0].value + l = len(tokens) + index = 1 + for index in range(1, l, 2): + token = tokens[index] + assert isinstance(token, TokenObject) + if token.name != tok.DOT: + break + name = name + '.' + tokens[index+1].value + return (index, name) + +def parse_argument(tokens): + """parses function call arguments""" + l = len(tokens) + index = 0 + arguments = [] + last_token = None + building_kw = False + kw_built = False + stararg_token = None + dstararg_token = None + while index < l: + cur_token = tokens[index] + index += 1 + if not isinstance(cur_token, TokenObject): + if not building_kw: + arguments.append(cur_token) + elif kw_built: + raise SyntaxError("non-keyword arg after keyword arg (%s)" % (cur_token)) + else: + last_token = arguments.pop() + assert isinstance(last_token, ast.Name) # used by rtyper + arguments.append(ast.Keyword(last_token.name, cur_token)) + building_kw = False + kw_built = True + elif cur_token.name == tok.COMMA: + continue + elif cur_token.name == tok.EQUAL: + building_kw = True + continue + elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: + if cur_token.name == tok.STAR: + stararg_token = tokens[index] + index += 1 + if index >= l: + break + index += 2 # Skip COMMA and DOUBLESTAR + dstararg_token = tokens[index] + break + return arguments, stararg_token, dstararg_token + + +def parse_arglist(tokens): + """returns names, defaults, flags""" + l = len(tokens) + index = 0 + defaults = [] + names = [] + flags = 0 + while index < l: + cur_token = tokens[index] + index += 1 + if not isinstance(cur_token, TokenObject): + # XXX: think of another way to write this test + defaults.append(cur_token) + elif cur_token.name == tok.COMMA: + # We could skip test COMMA by incrementing index cleverly + # but we might do some experiment on the grammar at some point + continue + elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: + if cur_token.name == tok.STAR: + cur_token = tokens[index] + index += 1 + if cur_token.name == tok.NAME: + names.append(cur_token.value) + flags |= consts.CO_VARARGS + index += 1 + if index >= l: + break + else: + # still more tokens to read + cur_token = tokens[index] + index += 1 + else: + raise ValueError("FIXME: SyntaxError (incomplete varags) ?") + if cur_token.name != tok.DOUBLESTAR: + raise ValueError("Unexpected token: %s" % cur_token) + cur_token = tokens[index] + index += 1 + if cur_token.name == tok.NAME: + names.append(cur_token.value) + flags |= consts.CO_VARKEYWORDS + index += 1 + else: + raise ValueError("FIXME: SyntaxError (incomplete varags) ?") + if index < l: + raise ValueError("unexpected token: %s" % tokens[index]) + elif cur_token.name == tok.NAME: + names.append(cur_token.value) + return names, defaults, flags + + +def parse_listcomp(tokens): + """parses 'for j in k for i in j if i %2 == 0' and returns + a GenExprFor instance + XXX: refactor with listmaker ? + """ + list_fors = [] + ifs = [] + index = 0 + while index < len(tokens): + if tokens[index].value == 'for': + index += 1 # skip 'for' + ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) + index += 2 # skip 'in' + iterable = tokens[index] + index += 1 + while index < len(tokens) and tokens[index].value == 'if': + ifs.append(ast.ListCompIf(tokens[index+1])) + index += 2 + list_fors.append(ast.ListCompFor(ass_node, iterable, ifs)) + ifs = [] + else: + raise ValueError('Unexpected token: %s' % tokens[index]) + return list_fors + + +def parse_genexpr_for(tokens): + """parses 'for j in k for i in j if i %2 == 0' and returns + a GenExprFor instance + XXX: if RPYTHON supports to pass a class object to a function, + we could refactor parse_listcomp and parse_genexpr_for, + and call : + - parse_listcomp(tokens, forclass=ast.GenExprFor, ifclass=...) + or: + - parse_listcomp(tokens, forclass=ast.ListCompFor, ifclass=...) + """ + genexpr_fors = [] + ifs = [] + index = 0 + while index < len(tokens): + if tokens[index].value == 'for': + index += 1 # skip 'for' + ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) + index += 2 # skip 'in' + iterable = tokens[index] + index += 1 + while index < len(tokens) and tokens[index].value == 'if': + ifs.append(ast.GenExprIf(tokens[index+1])) + index += 2 + genexpr_fors.append(ast.GenExprFor(ass_node, iterable, ifs)) + ifs = [] + else: + raise ValueError('Unexpected token: %s' % tokens[index]) + return genexpr_fors + + +def get_docstring(stmt): + """parses a Stmt node. + + If a docstring if found, the Discard node is **removed** + from and the docstring is returned. + + If no docstring is found, is left unchanged + and None is returned + """ + if not isinstance(stmt, ast.Stmt): + return None + doc = None + if len(stmt.nodes): + first_child = stmt.nodes[0] + if isinstance(first_child, ast.Discard): + expr = first_child.expr + if isinstance(expr, ast.Const): + # This *is* a docstring, remove it from stmt list + del stmt.nodes[0] + doc = expr.value + return doc + + +def to_lvalue(ast_node, OP): if isinstance( ast_node, ast.Name ): return ast.AssName( ast_node.name, OP ) elif isinstance(ast_node, ast.Tuple): nodes = [] for node in ast_node.getChildren(): - nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) + nodes.append(to_lvalue(node, OP)) + # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssTuple(nodes) elif isinstance(ast_node, ast.Getattr): expr = ast_node.expr @@ -38,29 +252,6 @@ return True return False -## building functions helpers -## -------------------------- -## -## Naming convention: -## to provide a function handler for a grammar rule name yyy -## you should provide a build_yyy( builder, nb ) function -## where builder is the AstBuilder instance used to build the -## ast tree and nb is the number of items this rule is reducing -## -## Example: -## for example if the rule -## term <- var ( '+' expr )* -## matches -## x + (2*y) + z -## build_term will be called with nb == 2 -## and get_atoms( builder, nb ) should return a list -## of 5 objects : Var TokenObject('+') Expr('2*y') TokenObject('+') Expr('z') -## where Var and Expr are AST subtrees and Token is a not yet -## reduced token -## -## AST_RULES is kept as a dictionnary to be rpython compliant this is the -## main reason why build_* functions are not methods of the AstBuilder class -## def get_atoms( builder, nb ): L = [] i = nb @@ -82,13 +273,92 @@ """temporary implementation""" return eval(value) + +## misc utilities, especially for power: rule +def reduce_callfunc(obj, arglist): + """generic factory for CallFunc nodes""" + assert isinstance(arglist, ArglistObject) + arguments, stararg, dstararg = arglist.value + return ast.CallFunc(obj, arguments, stararg, dstararg) + +def reduce_subscript(obj, subscript): + """generic factory for Subscript nodes""" + assert isinstance(subscript, SubscriptObject) + return ast.Subscript(obj, consts.OP_APPLY, subscript.value) + +def reduce_slice(obj, sliceobj): + """generic factory for Slice nodes""" + assert isinstance(sliceobj, SlicelistObject) + if sliceobj.name == 'slice': + start = sliceobj.value[0] + end = sliceobj.value[1] + return ast.Slice(obj, consts.OP_APPLY, start, end) + else: + return ast.Subscript(obj, consts.OP_APPLY, [ast.Sliceobj(sliceobj.value)]) + +def parse_attraccess(tokens): + """parses token list like ['a', '.', 'b', '.', 'c', ...] + + and returns an ast node : ast.Getattr(Getattr(Name('a'), 'b'), 'c' ...) + """ + result = tokens[0] + index = 1 + while index < len(tokens): + token = tokens[index] + if isinstance(token, TokenObject) and token.name == tok.DOT: + index += 1 + token = tokens[index] + assert isinstance(token, TokenObject) + result = ast.Getattr(result, token.value) + elif isinstance(token, ArglistObject): + result = reduce_callfunc(result, token) + elif isinstance(token, SubscriptObject): + result = reduce_subscript(result, token) + elif isinstance(token, SlicelistObject): + result = reduce_slice(result, token) + else: + assert False, "Don't know how to handle index %s of %s" % (index, tokens) + index += 1 + return result + + +## building functions helpers +## -------------------------- +## +## Builder functions used to reduce the builder stack into appropriate +## AST nodes. All the builder functions have the same interface +## +## Naming convention: +## to provide a function handler for a grammar rule name yyy +## you should provide a build_yyy( builder, nb ) function +## where builder is the AstBuilder instance used to build the +## ast tree and nb is the number of items this rule is reducing +## +## Example: +## for example if the rule +## term <- var ( '+' expr )* +## matches +## x + (2*y) + z +## build_term will be called with nb == 2 +## and get_atoms( builder, nb ) should return a list +## of 5 objects : Var TokenObject('+') Expr('2*y') TokenObject('+') Expr('z') +## where Var and Expr are AST subtrees and Token is a not yet +## reduced token +## +## AST_RULES is kept as a dictionnary to be rpython compliant this is the +## main reason why build_* functions are not methods of the AstBuilder class +## + def build_atom(builder, nb): L = get_atoms( builder, nb ) top = L[0] if isinstance(top, TokenObject): print "\t reducing atom (%s) (top.name) = %s" % (nb, top.name) if top.name == tok.LPAR: - builder.push( L[1] ) + if len(L) == 2: + builder.push(ast.Tuple([], top.line)) + else: + builder.push( L[1] ) elif top.name == tok.LSQB: if len(L) == 2: builder.push(ast.List([], top.line)) @@ -118,53 +388,21 @@ builder.push( ast.Const(s) ) # assert False, "TODO (String)" else: - raise ValueError, "unexpected tokens (%d): %s" % (nb,[ str(i) for i in L] ) - + raise ValueError, "unexpected tokens (%d): %s" % (nb, [str(i) for i in L]) + def build_power(builder, nb): + """power: atom trailer* ['**' factor]""" L = get_atoms(builder, nb) if len(L) == 1: - builder.push( L[0] ) - elif len(L) == 2: - if isinstance(L[1], ArglistObject): - arguments, stararg, dstararg = L[1].value - builder.push(ast.CallFunc(L[0], arguments, stararg, dstararg)) - elif isinstance(L[1], SubscriptObject): - subs = L[1].value - builder.push(ast.Subscript(L[0], consts.OP_APPLY, subs)) - elif isinstance(L[1], SlicelistObject): - if L[1].name == 'slice': - start = L[1].value[0] - end = L[1].value[1] - builder.push(ast.Slice(L[0], consts.OP_APPLY, start, end)) - else: # sliceobj (with 'step' argument) - builder.push(ast.Subscript(L[0], consts.OP_APPLY, [ast.Sliceobj(L[1].value)])) - else: - assert False, "TODO" - elif len(L) == 3: - if isinstance(L[1], TokenObject) and L[1].name == tok.DOT: - builder.push(ast.Getattr(L[0], L[2].value)) - else: - builder.push(ast.Power([L[0], L[2]])) - # FIXME: find a more general way to do this - elif isinstance(L[-1], ArglistObject): - # for an expression like 'a.b.c.append(3)', we want ['a', 'b', 'c'] - names = [] - for index in range(0, len(L)-1, 2): - names.append(L[index]) - while len(names) > 1: - left = names.pop(0) - right = names.pop(0) - assert isinstance(right, TokenObject) - names.insert(0, ast.Getattr(left, right.value)) - left = names[0] - arglist = L[-1] - assert isinstance(arglist, ArglistObject) - arguments, stararg, dstararg = arglist.value - builder.push(ast.CallFunc(left, arguments, stararg, dstararg)) - # FIXME: isinstance(L[-1], (SubscriptObject, SliceObject)) + builder.push(L[0]) else: - raise ValueError, "unexpected tokens: %s" % L + if isinstance(L[-2], TokenObject) and L[-2].name == tok.DOUBLESTAR: + obj = parse_attraccess(L[:-2]) + builder.push(ast.Power([obj, L[-1]])) + else: + obj = parse_attraccess(L) + builder.push(obj) def build_factor( builder, nb ): L = get_atoms( builder, nb ) @@ -421,6 +659,7 @@ """trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME """ L = get_atoms(builder, nb) + print "**** building trailer", L # Case 1 : '(' ... if L[0].name == tok.LPAR: if len(L) == 2: # and L[1].token == tok.RPAR: @@ -458,7 +697,8 @@ elif len(L) == 1: token = L[0] if isinstance(token, TokenObject) and token.name == tok.COLON: - builder.push(SlicelistObject('slice', [None, None, None], None)) + sliceinfos = [None, None, None] + builder.push(SlicelistObject('slice', sliceinfos, None)) else: # test builder.push(L[0]) @@ -482,7 +722,13 @@ sliceinfos[infosindex] = token if subscript_type == 'slice': if infosindex == 2: - builder.push(SlicelistObject('sliceobj', sliceinfos, None)) + sliceobj_infos = [] + for value in sliceinfos: + if value is None: + sliceobj_infos.append(ast.Const(None)) + else: + sliceobj_infos.append(value) + builder.push(SlicelistObject('sliceobj', sliceobj_infos, None)) else: builder.push(SlicelistObject('slice', sliceinfos, None)) else: @@ -616,6 +862,16 @@ else_ = L[8] builder.push(ast.For(assign, iterable, body, else_)) +def build_exprlist(builder, nb): + L = get_atoms(builder, nb) + if len(L) <= 2: + builder.push(L[0]) + else: + names = [] + for index in range(0, len(L), 2): + names.append(L[index]) + builder.push(ast.Tuple(names)) + def build_while_stmt(builder, nb): """while_stmt: 'while' test ':' suite ['else' ':' suite]""" @@ -712,12 +968,6 @@ def build_del_stmt(builder, nb): L = get_atoms(builder, nb) builder.push(to_lvalue(L[1], consts.OP_DELETE)) -## if isinstance(L[1], ast.Name): -## builder.push(ast.AssName(L[1].name, consts.OP_DELETE)) -## elif isinstance(L[1], ast.Getattr): -## assert "TODO", "build_del_stmt implementation is incomplete !" -## else: -## assert "TODO", "build_del_stmt implementation is incomplete !" def build_assert_stmt(builder, nb): @@ -820,217 +1070,6 @@ builder.push(ast.TryExcept(body, handlers, else_)) -def parse_except_clause(tokens): - """parses 'except' [test [',' test]] ':' suite - and returns a 4-tuple : (tokens_read, expr1, expr2, except_body) - """ - clause_length = 1 - # Read until end of except clause (bound by following 'else', - # or 'except' or end of tokens) - while clause_length < len(tokens): - token = tokens[clause_length] - if isinstance(token, TokenObject) and \ - (token.value == 'except' or token.value == 'else'): - break - clause_length += 1 - # if clause_length >= len(tokens): - # raise Exception - if clause_length == 3: - # case 'except: body' - return (3, None, None, tokens[2]) - elif clause_length == 4: - # case 'except Exception: body': - return (4, tokens[1], None, tokens[3]) - else: - # case 'except Exception, exc: body' - return (6, tokens[1], to_lvalue(tokens[3], consts.OP_ASSIGN), tokens[5]) - - -def parse_dotted_names(tokens): - """parses NAME('.' NAME)* and returns full dotted name - - this function doesn't assume that the list ends after the - last 'NAME' element - """ - name = tokens[0].value - l = len(tokens) - index = 1 - for index in range(1, l, 2): - token = tokens[index] - assert isinstance(token, TokenObject) - if token.name != tok.DOT: - break - name = name + '.' + tokens[index+1].value - return (index, name) - -def parse_argument(tokens): - """parses function call arguments""" - l = len(tokens) - index = 0 - arguments = [] - last_token = None - building_kw = False - kw_built = False - stararg_token = None - dstararg_token = None - while index < l: - cur_token = tokens[index] - index += 1 - if not isinstance(cur_token, TokenObject): - if not building_kw: - arguments.append(cur_token) - elif kw_built: - raise SyntaxError("non-keyword arg after keyword arg (%s)" % (cur_token)) - else: - last_token = arguments.pop() - assert isinstance(last_token, ast.Name) # used by rtyper - arguments.append(ast.Keyword(last_token.name, cur_token)) - building_kw = False - kw_built = True - elif cur_token.name == tok.COMMA: - continue - elif cur_token.name == tok.EQUAL: - building_kw = True - continue - elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: - if cur_token.name == tok.STAR: - stararg_token = tokens[index] - index += 1 - if index >= l: - break - index += 2 # Skip COMMA and DOUBLESTAR - dstararg_token = tokens[index] - break - return arguments, stararg_token, dstararg_token - - -def parse_arglist(tokens): - """returns names, defaults, flags""" - l = len(tokens) - index = 0 - defaults = [] - names = [] - flags = 0 - while index < l: - cur_token = tokens[index] - index += 1 - if not isinstance(cur_token, TokenObject): - # XXX: think of another way to write this test - defaults.append(cur_token) - elif cur_token.name == tok.COMMA: - # We could skip test COMMA by incrementing index cleverly - # but we might do some experiment on the grammar at some point - continue - elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: - if cur_token.name == tok.STAR: - cur_token = tokens[index] - index += 1 - if cur_token.name == tok.NAME: - names.append(cur_token.value) - flags |= consts.CO_VARARGS - index += 1 - if index >= l: - break - else: - # still more tokens to read - cur_token = tokens[index] - index += 1 - else: - raise ValueError("FIXME: SyntaxError (incomplete varags) ?") - if cur_token.name != tok.DOUBLESTAR: - raise ValueError("Unexpected token: %s" % cur_token) - cur_token = tokens[index] - index += 1 - if cur_token.name == tok.NAME: - names.append(cur_token.value) - flags |= consts.CO_VARKEYWORDS - index += 1 - else: - raise ValueError("FIXME: SyntaxError (incomplete varags) ?") - if index < l: - raise ValueError("unexpected token: %s" % tokens[index]) - elif cur_token.name == tok.NAME: - names.append(cur_token.value) - return names, defaults, flags - - -def parse_listcomp(tokens): - """parses 'for j in k for i in j if i %2 == 0' and returns - a GenExprFor instance - XXX: refactor with listmaker ? - """ - list_fors = [] - ifs = [] - index = 0 - while index < len(tokens): - if tokens[index].value == 'for': - index += 1 # skip 'for' - ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - index += 2 # skip 'in' - iterable = tokens[index] - index += 1 - while index < len(tokens) and tokens[index].value == 'if': - ifs.append(ast.ListCompIf(tokens[index+1])) - index += 2 - list_fors.append(ast.ListCompFor(ass_node, iterable, ifs)) - ifs = [] - else: - raise ValueError('Unexpected token: %s' % tokens[index]) - return list_fors - - -def parse_genexpr_for(tokens): - """parses 'for j in k for i in j if i %2 == 0' and returns - a GenExprFor instance - XXX: if RPYTHON supports to pass a class object to a function, - we could refactor parse_listcomp and parse_genexpr_for, - and call : - - parse_listcomp(tokens, forclass=ast.GenExprFor, ifclass=...) - or: - - parse_listcomp(tokens, forclass=ast.ListCompFor, ifclass=...) - """ - genexpr_fors = [] - ifs = [] - index = 0 - while index < len(tokens): - if tokens[index].value == 'for': - index += 1 # skip 'for' - ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) - index += 2 # skip 'in' - iterable = tokens[index] - index += 1 - while index < len(tokens) and tokens[index].value == 'if': - ifs.append(ast.GenExprIf(tokens[index+1])) - index += 2 - genexpr_fors.append(ast.GenExprFor(ass_node, iterable, ifs)) - ifs = [] - else: - raise ValueError('Unexpected token: %s' % tokens[index]) - return genexpr_fors - - -def get_docstring(stmt): - """parses a Stmt node. - - If a docstring if found, the Discard node is **removed** - from and the docstring is returned. - - If no docstring is found, is left unchanged - and None is returned - """ - if not isinstance(stmt, ast.Stmt): - return None - doc = None - if len(stmt.nodes): - first_child = stmt.nodes[0] - if isinstance(first_child, ast.Discard): - expr = first_child.expr - if isinstance(expr, ast.Const): - # This *is* a docstring, remove it from stmt list - del stmt.nodes[0] - doc = expr.value - return doc - ASTRULES = { # "single_input" : build_single_input, sym.atom : build_atom, @@ -1079,9 +1118,10 @@ sym.global_stmt : build_global_stmt, sym.raise_stmt : build_raise_stmt, sym.try_stmt : build_try_stmt, - # sym.parameters : build_parameters, + sym.exprlist : build_exprlist, } +## Stack elements definitions ################################### class RuleObject(ast.Node): """A simple object used to wrap a rule or token""" def __init__(self, name, count, src ): @@ -1125,8 +1165,13 @@ return "" % (self.get_name(), self.value) -class ArglistObject(ast.Node): - """helper class to build function's arg list""" +# FIXME: The ObjectAccessor family is probably not RPYTHON since +# some attributes have a different type depending on the subclass +class ObjectAccessor(ast.Node): + """base class for ArglistObject, SubscriptObject and SlicelistObject + + FIXME: think about a more appropriate name + """ def __init__(self, name, value, src): self.name = name self.value = value @@ -1134,39 +1179,36 @@ self.line = 0 # src.getline() self.col = 0 # src.getcol() +class ArglistObject(ObjectAccessor): + """helper class to build function's arg list + + self.value is the 3-tuple (names, defaults, flags) + """ def __str__(self): return "" % self.value def __repr__(self): return "" % self.value - -class SubscriptObject(ast.Node): - """helper class to build function's arg list""" - def __init__(self, name, value, src): - self.name = name - self.value = value - self.count = 0 - self.line = 0 # src.getline() - self.col = 0 # src.getcol() - +class SubscriptObject(ObjectAccessor): + """helper class to build subscript list + + self.value represents the __getitem__ argument + """ def __str__(self): return "" % self.value def __repr__(self): return "" % self.value -class SlicelistObject(ast.Node): - def __init__(self, name, value, src): - self.name = name - self.value = value -## self.begin = value[0] -## self.end = value[1] -## self.step = value[2] - self.count = 0 - self.line = 0 # src.getline() - self.col = 0 # src.getcol() +class SlicelistObject(ObjectAccessor): + """helper class to build slice objects + self.value is a 3-tuple (start, end, step) + self.name can either be 'slice' or 'sliceobj' depending + on if a step is specfied or not (see Python's AST + for more information on that) + """ def __str__(self): return "" % self.value @@ -1257,6 +1299,7 @@ return True def show_stack(before, after): + """debuggin helper function""" L1 = len(before) L2 = len(after) for i in range(max(L1,L2)): Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_simple_for_loop.py Thu Aug 11 12:59:47 2005 @@ -11,3 +11,5 @@ else: c = 3 +for index, val in enumerate(range(5)): + val *= 2 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Thu Aug 11 12:59:47 2005 @@ -29,7 +29,22 @@ "del foo.bar", "l[0]", "m[a,b]", -] + "a.b.c[d]", + "file('some.txt').read()", + "a[0].read()", + "a[1:1].read()", + "f('foo')('bar')('spam')", + "f('foo')('bar')('spam').read()[0]", + "a.b[0][0]", + "a.b[0][:]", + "a.b[0][::]", + "a.b[0][0].pop()[0].push('bar')('baz').spam", + "a.b[0].read()[1][2].foo().spam()[0].bar", + "a**2", + "a**2**2", + "a.b[0]**2", + "a.b[0].read()[1][2].foo().spam()[0].bar ** 2", + ] funccalls = [ "l = func()", @@ -109,10 +124,22 @@ slices = [ "l[:]", + "l[::]", "l[1:2]", "l[1:]", "l[:2]", + "l[1::]", + "l[:1:]", + "l[::1]", + "l[1:2:]", + "l[:1:2]", + "l[1::2]", "l[0:1:2]", + "a.b.l[:]", + "a.b.l[1:2]", + "a.b.l[1:]", + "a.b.l[:2]", + "a.b.l[0:1:2]", ] imports = [ @@ -263,6 +290,7 @@ "def f(x,y=1,z=t,**kwargs): return x+y", "def f(*args): return 1", "def f(**kwargs): return 1", + "def f(t=()): pass", ] docstrings = [ @@ -372,7 +400,7 @@ 'snippet_simple_in_expr.py', 'snippet_slice.py', 'snippet_whitespaces.py', -# 'snippet_samples.py', + 'snippet_samples.py', ] def test_snippets(): From cfbolz at codespeak.net Thu Aug 11 13:00:25 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 13:00:25 +0200 (CEST) Subject: [pypy-svn] r15959 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050811110025.00D0327B6C@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 13:00:25 2005 New Revision: 15959 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: give a more helpful error message as to samuele's suggestion Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Aug 11 13:00:25 2005 @@ -11,7 +11,7 @@ def free_non_gc_object(obj): - assert obj.__class__._raw_allocate_ + assert getattr(obj.__class__, "_raw_allocate_", False), "trying to free regular object" obj.__dict__ = {} obj.__class__ = FREED_OBJECT Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Thu Aug 11 13:00:25 2005 @@ -11,6 +11,8 @@ return self.a def method2(self): return 42 + class TestClass2(object): + pass t = TestClass(1) assert t.method1() == 1 assert t.method2() == 42 @@ -18,4 +20,4 @@ py.test.raises(GCError, "t.method1()") py.test.raises(GCError, "t.method2()") py.test.raises(GCError, "t.a") - + py.test.raises(AssertionError, "free_non_gc_object(TestClass2())") From cfbolz at codespeak.net Thu Aug 11 16:01:11 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 16:01:11 +0200 (CEST) Subject: [pypy-svn] r15962 - in pypy/dist/pypy: annotation rpython/memory rpython/memory/test Message-ID: <20050811140111.6524727B61@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 16:01:10 2005 New Revision: 15962 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/model.py pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/lladdress.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: renaming Address to address to have a naming scheme that is similar to that of lltype: Address will be the lltype that describes addresses. Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Thu Aug 11 16:01:10 2005 @@ -339,7 +339,7 @@ result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (x.__module__, x.__name__)) elif isinstance(x, lltype._ptr): result = SomePtr(lltype.typeOf(x)) - elif isinstance(x, lladdress.Address): + elif isinstance(x, lladdress.address): assert x is lladdress.NULL result= SomeAddress(is_null=True) elif callable(x) or isinstance(x, staticmethod): # XXX Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Thu Aug 11 16:01:10 2005 @@ -462,15 +462,15 @@ return False def lltype_or_address_to_annotation(T): - from pypy.rpython.memory.lladdress import Address - if T is Address: + from pypy.rpython.memory.lladdress import address + if T is address: return SomeAddress() return lltype_to_annotation(T) def annotation_to_lltype_or_address(s_ann): - from pypy.rpython.memory.lladdress import Address + from pypy.rpython.memory.lladdress import address if isinstance(s_ann, SomeAddress): - return Address + return address else: return annotation_to_lltype(s_ann) Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Thu Aug 11 16:01:10 2005 @@ -97,7 +97,7 @@ addr = self.convert(_ptr._obj) else: addr = lladdress.NULL - assert isinstance(addr, lladdress.Address) + assert isinstance(addr, lladdress.address) if inline_to_addr is not None: inline_to_addr.address[0] = addr return simulatorptr(TYPE, addr) Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 11 16:01:10 2005 @@ -4,7 +4,7 @@ from pypy.rpython.rarithmetic import r_uint -class Address(object): +class address(object): def __new__(cls, intaddress=0): if intaddress == 0: null = cls.__dict__.get("NULL") @@ -23,11 +23,11 @@ def __add__(self, offset): assert isinstance(offset, int) - return Address(self.intaddress + offset) + return address(self.intaddress + offset) def __sub__(self, other): if isinstance(other, int): - return Address(self.intaddress - other) + return address(self.intaddress - other) else: return self.intaddress - other.intaddress @@ -76,20 +76,20 @@ class _address_accessor(_accessor): format = "P" size = struct.calcsize("P") - convert_from = Address - convert_to = Address._getintattr + convert_from = address + convert_to = address._getintattr -Address.signed = property(_signed_accessor) -Address.unsigned = property(_unsigned_accessor) -Address.char = property(_char_accessor) -Address.address = property(_address_accessor) +address.signed = property(_signed_accessor) +address.unsigned = property(_unsigned_accessor) +address.char = property(_char_accessor) +address.address = property(_address_accessor) -NULL = Address() +NULL = address() simulator = MemorySimulator() def raw_malloc(size): - return Address(simulator.malloc(size)) + return address(simulator.malloc(size)) def raw_free(addr): simulator.free(addr.intaddress) @@ -98,7 +98,7 @@ simulator.memcopy(addr1.intaddress, addr2.intaddress, size) def get_address_of_object(obj): - return Address(simulator.get_address_of_object(obj)) + return address(simulator.get_address_of_object(obj)) def get_py_object(address): return simulator.get_py_object(address.intaddress) @@ -107,6 +107,6 @@ supported_access_types = {"signed": lltype.Signed, "unsigned": lltype.Unsigned, "char": lltype.Char, - "address": Address, + "address": address, } Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 11 16:01:10 2005 @@ -4,7 +4,7 @@ from pypy.annotation import model as annmodel from pypy.translator.annrpython import RPythonAnnotator from pypy.objspace.flow import FlowObjSpace -from pypy.rpython.memory.lladdress import Address, NULL +from pypy.rpython.memory.lladdress import address, NULL from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy from pypy.rpython.memory.lladdress import get_py_object, get_address_of_object from pypy.rpython.memory.simulator import MemorySimulatorError @@ -110,8 +110,8 @@ class TestAddressSimulation(object): def test_null_is_singleton(self): - assert Address() is NULL - assert Address() is Address(0) + assert address() is NULL + assert address() is address(0) def test_memory_access(self): addr = raw_malloc(1000) From adim at codespeak.net Thu Aug 11 16:32:41 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Thu, 11 Aug 2005 16:32:41 +0200 (CEST) Subject: [pypy-svn] r15963 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050811143241.F097727B61@code1.codespeak.net> Author: adim Date: Thu Aug 11 16:32:39 2005 New Revision: 15963 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: several improvements/bugfixes among which: - lvalue management for List and Slices - nested tuples in parameters (like in def f(a, (b, (c, d), e), f): pass) - removed bad SyntaxError raising in parse_arglist Now astbuilder works for all stdlib files (smaller than 10k) Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Thu Aug 11 16:32:39 2005 @@ -9,7 +9,7 @@ import pypy.interpreter.pyparser.pysymbol as sym import pypy.interpreter.pyparser.pytoken as tok -DEBUG_MODE = False +DEBUG_MODE = 0 ### Parsing utilites ################################################# @@ -72,8 +72,8 @@ if not isinstance(cur_token, TokenObject): if not building_kw: arguments.append(cur_token) - elif kw_built: - raise SyntaxError("non-keyword arg after keyword arg (%s)" % (cur_token)) + # elif kw_built: + # raise SyntaxError("non-keyword arg after keyword arg (%s)" % (cur_token)) else: last_token = arguments.pop() assert isinstance(last_token, ast.Name) # used by rtyper @@ -97,6 +97,36 @@ return arguments, stararg_token, dstararg_token +def parse_fpdef(tokens): + """fpdef: fpdef: NAME | '(' fplist ')' + fplist: fpdef (',' fpdef)* [','] + """ + # FIXME: will we need to implement a Stack class to be RPYTHON compliant ? + stack = [[],] # list of lists + tokens_read = 0 + to_be_closed = 1 # number of parenthesis to be closed + result = None + while to_be_closed > 0: + token = tokens[tokens_read] + tokens_read += 1 + if isinstance(token, TokenObject) and token.name == tok.COMMA: + continue + elif isinstance(token, TokenObject) and token.name == tok.LPAR: + stack.append([]) + to_be_closed += 1 + elif isinstance(token, TokenObject) and token.name == tok.RPAR: + to_be_closed -= 1 + elt = stack.pop() + if to_be_closed > 0: + stack[-1].append(tuple(elt)) + else: + stack.append(tuple(elt)) + else: + assert isinstance(token, TokenObject) + stack[-1].append(token.value) + assert len(stack) == 1, "At the end of parse_fpdef, len(stack) should be 1, got %s" % stack + return tokens_read, tuple(stack[0]) + def parse_arglist(tokens): """returns names, defaults, flags""" l = len(tokens) @@ -107,6 +137,8 @@ while index < l: cur_token = tokens[index] index += 1 +## if isinstance(cur_token, FPListObject): +## names.append(cur_token.value) if not isinstance(cur_token, TokenObject): # XXX: think of another way to write this test defaults.append(cur_token) @@ -114,6 +146,10 @@ # We could skip test COMMA by incrementing index cleverly # but we might do some experiment on the grammar at some point continue + elif cur_token.name == tok.LPAR: + tokens_read, name = parse_fpdef(tokens[index:]) + index += tokens_read + names.append(name) elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: if cur_token.name == tok.STAR: cur_token = tokens[index] @@ -234,13 +270,22 @@ nodes.append(to_lvalue(node, OP)) # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssTuple(nodes) + elif isinstance(ast_node, ast.List): + nodes = [] + for node in ast_node.getChildren(): + nodes.append(to_lvalue(node, OP)) + # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) + return ast.AssList(nodes) elif isinstance(ast_node, ast.Getattr): expr = ast_node.expr attrname = ast_node.attrname return ast.AssAttr(expr, attrname, OP) elif isinstance(ast_node, ast.Subscript): ast_node.flags = OP - return ast_node + return ast_node + elif isinstance(ast_node, ast.Slice): + ast_node.flags = OP + return ast_node else: assert False, "TODO" @@ -353,7 +398,6 @@ L = get_atoms( builder, nb ) top = L[0] if isinstance(top, TokenObject): - print "\t reducing atom (%s) (top.name) = %s" % (nb, top.name) if top.name == tok.LPAR: if len(L) == 2: builder.push(ast.Tuple([], top.line)) @@ -387,6 +431,8 @@ s += eval_string(token.value) builder.push( ast.Const(s) ) # assert False, "TODO (String)" + elif top.name == tok.BACKQUOTE: + builder.push(ast.Backquote(L[1])) else: raise ValueError, "unexpected tokens (%d): %s" % (nb, [str(i) for i in L]) @@ -535,19 +581,21 @@ def build_and_test( builder, nb ): return build_binary_expr( builder, nb, ast.And ) +def build_not_test(builder, nb): + L = get_atoms(builder, nb) + if len(L) == 1: + builder.push(L[0]) + elif len(L) == 2: + builder.push(ast.Not(L[1])) + else: + assert False, "not_test implementation incomplete (%s)" % L + def build_test( builder, nb ): return build_binary_expr(builder, nb, ast.Or) def build_testlist( builder, nb ): return build_binary_expr( builder, nb, ast.Tuple ) -def build_not_test( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) - if l==1: - builder.push( L[0] ) - return - def build_expr_stmt( builder, nb ): L = get_atoms( builder, nb ) l = len(L) @@ -594,7 +642,7 @@ if len(L) > 2: assert False, "return several stmts not implemented" elif len(L) == 1: - builder.push(ast.Return(Const(None), None)) # XXX lineno + builder.push(ast.Return(ast.Const(None), None)) # XXX lineno else: builder.push(ast.Return(L[1], None)) # XXX lineno @@ -659,7 +707,6 @@ """trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME """ L = get_atoms(builder, nb) - print "**** building trailer", L # Case 1 : '(' ... if L[0].name == tok.LPAR: if len(L) == 2: # and L[1].token == tok.RPAR: @@ -760,9 +807,11 @@ funcname = L[1] arglist = [] index = 3 - while not (isinstance(L[index], TokenObject) and L[index].name == tok.RPAR): - arglist.append(L[index]) - index += 1 + arglist = L[3:-3] + # while not (isinstance(L[index], TokenObject) and L[index].name == tok.COLON): + # arglist.append(L[index]) + # index += 1 + # arglist.pop() # remove ':' names, default, flags = parse_arglist(arglist) funcname = L[1].value arglist = L[2] @@ -785,10 +834,12 @@ basenames = [] body = L[6] base = L[3] - assert isinstance(base, ast.Tuple) - for node in base.nodes: - assert isinstance(node, ast.Name) - basenames.append(node) + if isinstance(base, ast.Tuple): + for node in base.nodes: + assert isinstance(node, ast.Name) + basenames.append(node) + else: + basenames.append(base) doc = get_docstring(body) builder.push(ast.Class(classname, basenames, doc, body)) @@ -872,6 +923,14 @@ names.append(L[index]) builder.push(ast.Tuple(names)) +def build_fplist(builder, nb): + """fplist: fpdef (',' fpdef)* [',']""" + L = get_atoms(builder, nb) + names = [] + for index in range(0, len(L), 2): + names.append(L[index].value) + builder.push(FPListObject('fplist', tuple(names), None)) + def build_while_stmt(builder, nb): """while_stmt: 'while' test ':' suite ['else' ':' suite]""" @@ -1084,6 +1143,7 @@ sym.comparison : build_comparison, sym.comp_op : build_comp_op, sym.and_test : build_and_test, + sym.not_test : build_not_test, sym.test : build_test, sym.testlist : build_testlist, sym.expr_stmt : build_expr_stmt, @@ -1119,6 +1179,7 @@ sym.raise_stmt : build_raise_stmt, sym.try_stmt : build_try_stmt, sym.exprlist : build_exprlist, + # sym.fplist : build_fplist, } ## Stack elements definitions ################################### @@ -1165,6 +1226,21 @@ return "" % (self.get_name(), self.value) +class FPListObject(ast.Node): + """store temp informations for fplist""" + def __init__(self, name, value, src): + self.name = name + self.value = value + self.count = 0 + self.line = 0 # src.getline() + self.col = 0 # src.getcol() + + def __str__(self): + return "" % (self.value,) + + def __repr__(self): + return "" % (self.value,) + # FIXME: The ObjectAccessor family is probably not RPYTHON since # some attributes have a different type depending on the subclass class ObjectAccessor(ast.Node): @@ -1232,7 +1308,8 @@ return AstBuilderContext(self.rule_stack) def restore(self, ctx): - print "Restoring context (%s)" % (len(ctx.rule_stack)) + if DEBUG_MODE: + print "Restoring context (%s)" % (len(ctx.rule_stack)) assert isinstance(ctx, AstBuilderContext) self.rule_stack = ctx.rule_stack @@ -1242,9 +1319,11 @@ def push(self, obj): self.rule_stack.append( obj ) if not isinstance(obj, RuleObject) and not isinstance(obj, TokenObject): - print "Pushed:", str(obj), len(self.rule_stack) + if DEBUG_MODE: + print "Pushed:", str(obj), len(self.rule_stack) elif isinstance(obj, TempRuleObject): - print "Pushed:", str(obj), len(self.rule_stack) + if DEBUG_MODE: + print "Pushed:", str(obj), len(self.rule_stack) # print "\t", self.rule_stack def push_tok(self, name, value, src ): @@ -1257,18 +1336,20 @@ # Do nothing, keep rule on top of the stack rule_stack = self.rule_stack[:] if rule.is_root(): - print "ALT:", sym.sym_name[rule.codename], self.rule_stack + if DEBUG_MODE: + print "ALT:", sym.sym_name[rule.codename], self.rule_stack F = ASTRULES.get(rule.codename) if F: # print "REDUCING ALTERNATIVE %s" % sym.sym_name[rule.codename] F( self, 1 ) else: - print "No reducing implementation for %s, just push it on stack" % ( - sym.sym_name[rule.codename]) + if DEBUG_MODE: + print "No reducing implementation for %s, just push it on stack" % ( + sym.sym_name[rule.codename]) self.push_rule( rule.codename, 1, source ) else: self.push_rule( rule.codename, 1, source ) - if DEBUG_MODE: + if DEBUG_MODE > 1: show_stack(rule_stack, self.rule_stack) x = raw_input("Continue ?") return True @@ -1277,24 +1358,27 @@ """ """ rule_stack = self.rule_stack[:] if rule.is_root(): - print "SEQ:", sym.sym_name[rule.codename] + if DEBUG_MODE: + print "SEQ:", sym.sym_name[rule.codename] F = ASTRULES.get(rule.codename) if F: # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename] F( self, elts_number ) else: - print "No reducing implementation for %s, just push it on stack" % ( - sym.sym_name[rule.codename]) + if DEBUG_MODE: + print "No reducing implementation for %s, just push it on stack" % ( + sym.sym_name[rule.codename]) self.push_rule( rule.codename, elts_number, source ) else: self.push_rule( rule.codename, elts_number, source ) - if DEBUG_MODE: + if DEBUG_MODE > 1: show_stack(rule_stack, self.rule_stack) x = raw_input("Continue ?") return True def token(self, name, value, source): - print "TOK:", tok.tok_name[name], name, value + if DEBUG_MODE: + print "TOK:", tok.tok_name[name], name, value self.push_tok( name, value, source ) return True Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Thu Aug 11 16:32:39 2005 @@ -44,6 +44,14 @@ "a**2**2", "a.b[0]**2", "a.b[0].read()[1][2].foo().spam()[0].bar ** 2", + "l[start:end] = l2", + "l[::] = l2", + "a = `s`", + "a = `1 + 2 + f(3, 4)`", + "[a, b] = c", + "(a, b) = c", + "[a, (b,c), d] = e", + "a, (b, c), d = e", ] funccalls = [ @@ -55,6 +63,13 @@ "l = func(10, 12, a, b=c)", "e = l.pop(3)", "e = k.l.pop(3)", + "simplefilter('ignore', category=PendingDeprecationWarning, append=1)", + """methodmap = dict(subdirs=phase4, + same_files=phase3, diff_files=phase3, funny_files=phase3, + common_dirs = phase2, common_files=phase2, common_funny=phase2, + common=phase1, left_only=phase1, right_only=phase1, + left_list=phase0, right_list=phase0)""", + "odata = b2a_qp(data, quotetabs = quotetabs, header = header)", ] listmakers = [ @@ -168,7 +183,9 @@ a += 3 else: a += 4 -""" +""", + "if a and not b == c: pass", + "if a and not not not b == c: pass", ] asserts = [ @@ -290,7 +307,10 @@ "def f(x,y=1,z=t,**kwargs): return x+y", "def f(*args): return 1", "def f(**kwargs): return 1", - "def f(t=()): pass", + "def f(t=()): pass", + "def f(a, b, (c, d), e): pass", + "def f(a, b, (c, (d, e), f, (g, h))): pass", + "def f(a, b, (c, (d, e), f, (g, h)), i): pass", ] docstrings = [ @@ -306,6 +326,15 @@ ''' ] +returns = [ + 'def f(): return', + 'def f(): return 1', + 'def f(): return a.b', + 'def f(): return a', + 'def f(): return a,b,c,d', + 'return (a,b,c,d)', + ] + TESTS = [ expressions, comparisons, @@ -330,6 +359,7 @@ if_stmts, tryexcepts, docstrings, + returns, ] TARGET_DICT = { @@ -356,6 +386,7 @@ print print "BUILT:", r1.rule_stack[-1] print "-" * 30 + # r1.rule_stack[-1].equals(ast) assert ast == r1.rule_stack[-1], 'failed on %r' % (expr) @@ -409,3 +440,19 @@ source = file(filepath).read() yield check_expression, source, 'exec' +# FIXME: find the sys' attriubte that define this +STDLIB_PATH = os.path.dirname(os.__file__) +def test_on_stdlib(): + py.test.skip('too ambitious for now (and time consuming)') + for basename in os.listdir(STDLIB_PATH): + if basename != 'warnings.py': + continue + if not basename.endswith('.py'): + continue + filepath = os.path.join(STDLIB_PATH, basename) + size = os.stat(filepath)[6] + # filter on size + if size <= 10000: + print "TESTING", filepath + source = file(filepath).read() + yield check_expression, source, 'exec' From adim at codespeak.net Thu Aug 11 16:50:44 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Thu, 11 Aug 2005 16:50:44 +0200 (CEST) Subject: [pypy-svn] r15964 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050811145044.427D627B61@code1.codespeak.net> Author: adim Date: Thu Aug 11 16:50:42 2005 New Revision: 15964 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: removed inconsistent assert Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Thu Aug 11 16:50:42 2005 @@ -836,7 +836,6 @@ base = L[3] if isinstance(base, ast.Tuple): for node in base.nodes: - assert isinstance(node, ast.Name) basenames.append(node) else: basenames.append(base) Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Thu Aug 11 16:50:42 2005 @@ -313,6 +313,10 @@ "def f(a, b, (c, (d, e), f, (g, h)), i): pass", ] +one_stmt_classdefs = [ + "class Pdb(bdb.Bdb, cmd.Cmd): pass", + ] + docstrings = [ '''def foo(): """foo docstring""" @@ -355,6 +359,7 @@ ] EXEC_INPUTS = [ + one_stmt_classdefs, one_stmt_funcdefs, if_stmts, tryexcepts, @@ -445,8 +450,6 @@ def test_on_stdlib(): py.test.skip('too ambitious for now (and time consuming)') for basename in os.listdir(STDLIB_PATH): - if basename != 'warnings.py': - continue if not basename.endswith('.py'): continue filepath = os.path.join(STDLIB_PATH, basename) From cfbolz at codespeak.net Thu Aug 11 17:01:55 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 17:01:55 +0200 (CEST) Subject: [pypy-svn] r15965 - in pypy/dist/pypy: annotation rpython/memory Message-ID: <20050811150155.107DC27B61@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 17:01:54 2005 New Revision: 15965 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/model.py pypy/dist/pypy/rpython/memory/lladdress.py Log: added Primitive instance Address to lladdress and use this consistently (thanks samuele). Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Thu Aug 11 17:01:54 2005 @@ -659,13 +659,13 @@ class __extend__(pairtype(SomeTypedAddressAccess, SomeInteger)): def getitem((s_taa, s_int)): - from pypy.annotation.model import lltype_or_address_to_annotation - return lltype_or_address_to_annotation(s_taa.type) + from pypy.annotation.model import lltype_to_annotation + return lltype_to_annotation(s_taa.type) getitem.can_only_throw = [] def setitem((s_taa, s_int), s_value): - from pypy.annotation.model import annotation_to_lltype_or_address - assert annotation_to_lltype_or_address(s_value) is s_taa.type + from pypy.annotation.model import annotation_to_lltype + assert annotation_to_lltype(s_value) is s_taa.type setitem.can_only_throw = [] Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Thu Aug 11 17:01:54 2005 @@ -387,6 +387,30 @@ def can_be_none(self): return False +# ____________________________________________________________ +# memory addresses + +from pypy.rpython.memory import lladdress + +class SomeAddress(SomeObject): + def __init__(self, is_null=False): + self.is_null = is_null + + def can_be_none(self): + return False + + +# The following class is used to annotate the intermediate value that +# appears in expressions of the form: +# addr.signed[offset] and addr.signed[offset] = value + +class SomeTypedAddressAccess(SomeObject): + def __init__(self, type): + self.type = type + + def can_be_none(self): + return False + #____________________________________________________________ # annotation of low-level types @@ -407,6 +431,7 @@ (SomeFloat(), lltype.Float), (SomeChar(), lltype.Char), (SomeUnicodeCodePoint(), lltype.UniChar), + (SomeAddress(), lladdress.Address), ] def annotation_to_lltype(s_val, info=None): @@ -438,41 +463,6 @@ from bookkeeper import getbookkeeper return getbookkeeper().immutablevalue(None) return lltype_to_annotation(lltype.typeOf(v)) - -# ____________________________________________________________ -# memory addresses - -class SomeAddress(SomeObject): - def __init__(self, is_null=False): - self.is_null = is_null - - def can_be_none(self): - return False - - -# The following class is used to annotate the intermediate value that -# appears in expressions of the form: -# addr.signed[offset] and addr.signed[offset] = value - -class SomeTypedAddressAccess(SomeObject): - def __init__(self, type): - self.type = type - - def can_be_none(self): - return False - -def lltype_or_address_to_annotation(T): - from pypy.rpython.memory.lladdress import address - if T is address: - return SomeAddress() - return lltype_to_annotation(T) - -def annotation_to_lltype_or_address(s_ann): - from pypy.rpython.memory.lladdress import address - if isinstance(s_ann, SomeAddress): - return address - else: - return annotation_to_lltype(s_ann) # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 11 17:01:54 2005 @@ -1,5 +1,4 @@ import struct -from pypy.rpython import lltype from pypy.rpython.memory.simulator import MemorySimulator from pypy.rpython.rarithmetic import r_uint @@ -104,9 +103,12 @@ return simulator.get_py_object(address.intaddress) +from pypy.rpython import lltype +Address = lltype.Primitive("Address", NULL) + + supported_access_types = {"signed": lltype.Signed, "unsigned": lltype.Unsigned, "char": lltype.Char, - "address": address, + "address": Address, } - From cfbolz at codespeak.net Thu Aug 11 17:23:54 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 17:23:54 +0200 (CEST) Subject: [pypy-svn] r15967 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050811152354.1B0E127B61@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 17:23:53 2005 New Revision: 15967 Modified: pypy/dist/pypy/rpython/memory/test/test_address.py Log: added (failing) tests that check whether addresses are rtyped correctly. Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 11 17:23:53 2005 @@ -4,9 +4,11 @@ from pypy.annotation import model as annmodel from pypy.translator.annrpython import RPythonAnnotator from pypy.objspace.flow import FlowObjSpace +from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.memory.lladdress import address, NULL from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy from pypy.rpython.memory.lladdress import get_py_object, get_address_of_object +from pypy.rpython.memory.lladdress import Address from pypy.rpython.memory.simulator import MemorySimulatorError class TestAddressAnnotation(object): @@ -108,6 +110,75 @@ assert not f(0) assert not f(-1) + +class TestAddressRTyping(object): + def DONOTtest_null(self): + def f(): + return NULL + a = RPythonAnnotator() + s = a.build_types(f, []) + rtyper = RPythonTyper(a) + rtyper.specialize() + rtyp = a.translator.flowgraphs[f].returnblock.inputargs[0].concretetype + assert rtyp == Address + + def DONOTtest_raw_malloc(self): + def f(): + return raw_malloc(100) + a = RPythonAnnotator() + s = a.build_types(f, []) + rtyper = RPythonTyper(a) + rtyper.specialize() #does not raise + + def DONOTtest_raw_free(self): + def f(addr): + raw_free(addr) + a = RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeAddress()]) + rtyper = RPythonTyper(a) + rtyper.specialize() #does not raise + + def DONOTtest_memcopy(self): + def f(addr1, addr2): + raw_memcopy(addr1, addr2, 100) + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, [annmodel.SomeAddress(), annmodel.SomeAddress()]) + rtyper = RPythonTyper(a) + rtyper.specialize() #does not raise + + def DONOTtest_memory_access(self): + def f(offset, value): + addr = raw_malloc(offset * 2 + 1) + addr.signed[offset] = value + return addr.signed[offset] + a = RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger(), annmodel.SomeInteger()]) + rtyper = RPythonTyper(a) + rtyper.specialize() #does not raise + + def DONOTtest_address_arithmetic(self): + def f(offset, char): + addr = raw_malloc(10000) + same_offset = (addr + offset) - addr + addr.char[offset] = char + return (addr + same_offset).char[0] + a = RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger(), annmodel.SomeChar()]) + rtyper = RPythonTyper(a) + rtyper.specialize() #does not raise + + def DONOTtest_address_comparison(self): + def f(offset): + return NULL < NULL + offset + a = RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeInteger()]) + rtyper = RPythonTyper(a) + rtyper.specialize() #does not raise + graph = a.translator.flowgraphs[f] + assert graph.startblock.operations[0].result.concretetype == Address + + class TestAddressSimulation(object): def test_null_is_singleton(self): assert address() is NULL From adim at codespeak.net Thu Aug 11 18:10:13 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Thu, 11 Aug 2005 18:10:13 +0200 (CEST) Subject: [pypy-svn] r15969 - in pypy/dist/pypy/interpreter/pyparser: . test test/samples Message-ID: <20050811161013.3B9A227B6D@code1.codespeak.net> Author: adim Date: Thu Aug 11 18:10:10 2005 New Revision: 15969 Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_decorators.py Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: implemented decorators Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Thu Aug 11 18:10:10 2005 @@ -346,7 +346,12 @@ and returns an ast node : ast.Getattr(Getattr(Name('a'), 'b'), 'c' ...) """ - result = tokens[0] + token = tokens[0] + # XXX HACK for when parse_attraccess is called from build_decorator + if isinstance(token, TokenObject): + result = ast.Name(token.value) + else: + result = token index = 1 while index < len(tokens): token = tokens[index] @@ -800,10 +805,35 @@ builder.push(ast.List(nodes)) +def build_decorator(builder, nb): + """decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE""" + L = get_atoms(builder, nb) + print "***** decorator", L + nodes = [] + # remove '@', '(' and ')' from L and use parse_attraccess + for token in L[1:]: + if isinstance(token, TokenObject) and \ + token.name in (tok.LPAR, tok.RPAR, tok.NEWLINE): + # skip those ones + continue + else: + nodes.append(token) + obj = parse_attraccess(nodes) + builder.push(obj) + def build_funcdef(builder, nb): """funcdef: [decorators] 'def' NAME parameters ':' suite """ L = get_atoms(builder, nb) + index = 0 + decorators = [] + decorator_node = None + while not (isinstance(L[index], TokenObject) and L[index].value == 'def'): + decorators.append(L[index]) + index += 1 + if decorators: + decorator_node = ast.Decorators(decorators) + L = L[index:] funcname = L[1] arglist = [] index = 3 @@ -818,7 +848,7 @@ code = L[-1] doc = get_docstring(code) # FIXME: decorators and docstring ! - builder.push(ast.Function(None, funcname, names, default, flags, doc, code)) + builder.push(ast.Function(decorator_node, funcname, names, default, flags, doc, code)) def build_classdef(builder, nb): @@ -1178,6 +1208,7 @@ sym.raise_stmt : build_raise_stmt, sym.try_stmt : build_try_stmt, sym.exprlist : build_exprlist, + sym.decorator : build_decorator, # sym.fplist : build_fplist, } Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_decorators.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_decorators.py Thu Aug 11 18:10:10 2005 @@ -0,0 +1,18 @@ +# Function(Decorators([Name('foo')]), 'f', ['a', 'b'], [], 0, None, Stmt([Pass()])) + at foo +def f(a, b): + pass + + at accepts(int, (int,float)) + at returns((int,float)) +def func(arg1, arg2): + return arg1 * arg2 + + +## Stmt([Function(Decorators([CallFunc(Getattr(Getattr(Name('mod1'), 'mod2'), 'accepts'), [Name('int'), Tuple([Name('int'), Name('float')])], None, None), +## CallFunc(Getattr(Getattr(Name('mod1'), 'mod2'), 'returns'), [Tuple([Name('int'), Name('float')])], None, None)]), +## 'func', ['arg1', 'arg2'], [], 0, None, Stmt([Return(Mul((Name('arg1'), Name('arg2'))))]))]) + at mod1.mod2.accepts(int, (int,float)) + at mod1.mod2.returns((int,float)) +def func(arg1, arg2): + return arg1 * arg2 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Thu Aug 11 18:10:10 2005 @@ -437,6 +437,7 @@ 'snippet_slice.py', 'snippet_whitespaces.py', 'snippet_samples.py', + 'snippet_decorators.py', ] def test_snippets(): From cfbolz at codespeak.net Thu Aug 11 18:10:13 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 18:10:13 +0200 (CEST) Subject: [pypy-svn] r15970 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050811161013.CD45827B6D@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 18:10:13 2005 New Revision: 15970 Modified: pypy/dist/pypy/rpython/memory/simulator.py pypy/dist/pypy/rpython/memory/test/test_simulator.py Log: oops, bad idea. the memory simulator used the total size of all memory allocated to this point as the current memory size. Test + fix. Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Thu Aug 11 18:10:13 2005 @@ -94,6 +94,7 @@ self.freememoryaddress = 4 + SIZE_OF_OBJECT_BLOCK if ram_size is not None: self.size_of_simulated_ram = ram_size + self.current_size = 0 def find_block(self, address): if address >= self.freememoryaddress: @@ -115,7 +116,8 @@ result = self.freememoryaddress self.blocks.append(MemoryBlock(result, size)) self.freememoryaddress += size - if self.freememoryaddress > self.size_of_simulated_ram: + self.current_size += size + if self.current_size + size > self.size_of_simulated_ram: raise MemorySimulatorError, "out of memory" return result @@ -125,6 +127,7 @@ block = self.find_block(baseaddress) if baseaddress != block.baseaddress: raise MemorySimulatorError, "trying to free address not malloc'ed" + self.current_size -= block.size block.free() def getstruct(self, fmt, address): Modified: pypy/dist/pypy/rpython/memory/test/test_simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_simulator.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_simulator.py Thu Aug 11 18:10:13 2005 @@ -63,9 +63,14 @@ def test_out_of_memory(self): sim = MemorySimulator(1 * 1024 * 1024) def f(): - for i in xrange(10000000): + for i in xrange(10000): sim.malloc(4096) py.test.raises(MemorySimulatorError, f) + sim = MemorySimulator(1 * 1024 * 1024) + def g(): + for i in xrange(10000): + sim.free(sim.malloc(4096)) + g() #does not raise def test_object_access(self): sim = MemorySimulator() From pedronis at codespeak.net Thu Aug 11 18:47:19 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 11 Aug 2005 18:47:19 +0200 (CEST) Subject: [pypy-svn] r15971 - in pypy/dist/pypy/translator/c: src test Message-ID: <20050811164719.4F34A27B61@code1.codespeak.net> Author: pedronis Date: Thu Aug 11 18:47:16 2005 New Revision: 15971 Modified: pypy/dist/pypy/translator/c/src/ll_math.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: issue104 testing added error handling in ll_math.h. After the changes in floatobject.py we don't need for now version of float ops raising exceptions Modified: pypy/dist/pypy/translator/c/src/ll_math.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_math.h (original) +++ pypy/dist/pypy/translator/c/src/ll_math.h Thu Aug 11 18:47:16 2005 @@ -7,105 +7,216 @@ flag set. */ +/* xxx macro from pyport.h, at some point define our owns */ +/* xxx this 2.3 name is later deprecated */ +#define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW + +int ll_math_is_error(double x) { + if (errno == ERANGE) { + if (!x) + return 0; + RPyRaiseSimpleException(PyExc_OverflowError, "math range error"); + } else { + RPyRaiseSimpleException(PyExc_ValueError, "math domain error"); + } + return 1; +} + +#define LL_MATH_ERROR_RESET errno = 0 + +#define LL_MATH_CHECK_ERROR(x, errret) do { \ + LL_MATH_SET_ERANGE_IF_MATH_ERROR(x); \ + if (errno && ll_math_is_error(x)) \ + return errret; \ +} while(0) + -/* XXX completely ignoring exceptions/error checking for now */ double LL_math_pow(double x, double y) { - return pow(x, y); + double r; + LL_MATH_ERROR_RESET; + r = pow(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } RPyFREXP_RESULT* LL_math_frexp(double x) { - int expo; - double m = frexp(x, &expo); - return ll_frexp_result(m, expo); + int expo; + double m; + LL_MATH_ERROR_RESET; + m= frexp(x, &expo); + LL_MATH_CHECK_ERROR(m, NULL); + return ll_frexp_result(m, expo); } double LL_math_atan2(double x, double y) { - return atan2(x, y); + double r; + LL_MATH_ERROR_RESET; + r = atan2(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_fmod(double x, double y) { - return fmod(x, y); + double r; + LL_MATH_ERROR_RESET; + r = fmod(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_ldexp(double x, long y) { - return ldexp(x, (int) y); + double r; + LL_MATH_ERROR_RESET; + r = ldexp(x, (int) y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_hypot(double x, double y) { - return hypot(x, y); + double r; + LL_MATH_ERROR_RESET; + r = hypot(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } RPyMODF_RESULT* LL_math_modf(double x) { - double intpart; - double fracpart = modf(x, &intpart); - return ll_modf_result(fracpart, intpart); + double intpart, fracpart; + LL_MATH_ERROR_RESET; + fracpart = modf(x, &intpart); + LL_MATH_CHECK_ERROR(fracpart, NULL); + return ll_modf_result(fracpart, intpart); } /* simple math function */ double LL_math_acos(double x) { - return acos(x); + double r; + LL_MATH_ERROR_RESET; + r = acos(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_asin(double x) { - return asin(x); + double r; + LL_MATH_ERROR_RESET; + r = asin(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_atan(double x) { - return atan(x); + double r; + LL_MATH_ERROR_RESET; + r = atan(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_ceil(double x) { - return ceil(x); + double r; + LL_MATH_ERROR_RESET; + r = ceil(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_cos(double x) { - return cos(x); + double r; + LL_MATH_ERROR_RESET; + r = cos(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_cosh(double x) { - return cosh(x); + double r; + LL_MATH_ERROR_RESET; + r = cosh(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_exp(double x) { - return exp(x); + double r; + LL_MATH_ERROR_RESET; + r = exp(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_fabs(double x) { - return fabs(x); + double r; + LL_MATH_ERROR_RESET; + r = fabs(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_floor(double x) { - return floor(x); + double r; + LL_MATH_ERROR_RESET; + r = floor(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_log(double x) { - return log(x); + double r; + LL_MATH_ERROR_RESET; + r = log(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_log10(double x) { - return log10(x); + double r; + LL_MATH_ERROR_RESET; + r = log10(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_sin(double x) { - return sin(x); + double r; + LL_MATH_ERROR_RESET; + r = sin(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_sinh(double x) { - return sinh(x); + double r; + LL_MATH_ERROR_RESET; + r = sinh(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_sqrt(double x) { - return sqrt(x); + double r; + LL_MATH_ERROR_RESET; + r = sqrt(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_tan(double x) { - return tan(x); + double r; + LL_MATH_ERROR_RESET; + r = tan(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } double LL_math_tanh(double x) { - return tanh(x); + double r; + LL_MATH_ERROR_RESET; + r = tanh(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; } Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Thu Aug 11 18:47:16 2005 @@ -196,6 +196,21 @@ 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) + py.test.raises(ValueError, f, -1.0) + py.test.raises(OverflowError, f, 0.0) + import math + def fn(y): + return math.fmod(1.0, y) + f = compile(fn, [float]) + py.test.raises(ValueError, f, 0.0) + + def test_os_path_exists(): tmpfile = str(udir.join('test_os_path_exists.TMP')) def fn(): From cfbolz at codespeak.net Thu Aug 11 19:21:28 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 19:21:28 +0200 (CEST) Subject: [pypy-svn] r15972 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050811172128.08BE727B64@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 19:21:27 2005 New Revision: 15972 Added: pypy/dist/pypy/rpython/memory/support.py pypy/dist/pypy/rpython/memory/test/test_support.py Log: very simple linked list. (and really stupidly implemented: really should use some sort of pool for all those allocations) Added: pypy/dist/pypy/rpython/memory/support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/support.py Thu Aug 11 19:21:27 2005 @@ -0,0 +1,36 @@ +from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL + +import struct + +INT_SIZE = struct.calcsize("i") + +class AddressLinkedList(object): + _raw_allocate_ = True + def __init__(self): + self.first = NULL + self.last = NULL + + def append(self, addr): + if addr == NULL: + return + new = raw_malloc(2 * INT_SIZE) + if self.first == NULL: + self.first = new + else: + self.last.address[0] = new + self.last = new + new.address[0] = NULL + new.address[1] = addr + + def pop(self): + if self.first == NULL: + return NULL + result = self.first.address[1] + next = self.first.address[0] + raw_free(self.first) + self.first = next + return result + + def free(self): + while self.pop() != NULL: + pass Added: pypy/dist/pypy/rpython/memory/test/test_support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/test/test_support.py Thu Aug 11 19:21:27 2005 @@ -0,0 +1,30 @@ +from pypy.rpython.memory.gc import free_non_gc_object +from pypy.rpython.memory.support import AddressLinkedList +from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL + +class TestAddressLinkedList(object): + def test_simple_access(self): + addr = raw_malloc(100) + ll = AddressLinkedList() + ll.append(addr) + ll.append(addr + 1) + ll.append(addr + 2) + a = ll.pop() + assert a == addr + a = ll.pop() + assert a - addr == 1 + a = ll.pop() + assert a - addr == 2 + assert ll.pop() == NULL + assert ll.pop() == NULL + ll.append(addr) + ll.free() + free_non_gc_object(ll) + ll = AddressLinkedList() + ll.append(addr) + ll.append(addr + 1) + ll.append(addr + 2) + ll.free() + free_non_gc_object(ll) + raw_free(addr) + From cfbolz at codespeak.net Thu Aug 11 20:25:57 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 20:25:57 +0200 (CEST) Subject: [pypy-svn] r15974 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050811182557.7F4A527B64@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 20:25:56 2005 New Revision: 15974 Modified: pypy/dist/pypy/rpython/memory/lladdress.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: raise an error when trying to access NULL pointer Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 11 20:25:56 2005 @@ -1,5 +1,5 @@ import struct -from pypy.rpython.memory.simulator import MemorySimulator +from pypy.rpython.memory.simulator import MemorySimulator, MemorySimulatorError from pypy.rpython.rarithmetic import r_uint @@ -44,6 +44,8 @@ class _accessor(object): def __init__(self, addr): + if addr == NULL: + raise MemorySimulatorError("trying to access NULL pointer") self.intaddress = addr.intaddress def __getitem__(self, offset): result = simulator.getstruct(self.format, Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 11 20:25:56 2005 @@ -190,6 +190,7 @@ assert addr.unsigned[0] == sys.maxint * 2 + 1 addr.address[0] = addr assert addr.address[0] == addr + py.test.raises(MemorySimulatorError, "NULL.signed[0]") def test_pointer_arithmetic(self): addr = raw_malloc(100) From cfbolz at codespeak.net Thu Aug 11 20:36:15 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 20:36:15 +0200 (CEST) Subject: [pypy-svn] r15975 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050811183615.3AF2127B64@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 20:36:14 2005 New Revision: 15975 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: implemented a very naive, inefficient Mark and Sweep GC. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Aug 11 20:36:14 2005 @@ -1,5 +1,9 @@ +from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL +from pypy.rpython.memory.support import AddressLinkedList import struct +INT_SIZE = struct.calcsize("i") + class GCError(Exception): pass @@ -15,3 +19,66 @@ obj.__dict__ = {} obj.__class__ = FREED_OBJECT + +class MarkSweepGC(object): + _raw_allocate_ = True + def __init__(self, objectmodel, collect_every_bytes): + self.bytes_malloced = 0 + self.collect_every_bytes = collect_every_bytes + #need to maintain a list of malloced objects, since we used the systems + #allocator and can't walk the heap + self.malloced_objects = AddressLinkedList() + self.objectmodel = objectmodel + + def malloc(self, typeid, size): + if self.bytes_malloced > self.collect_every_bytes: + self.collect() + result = raw_malloc(size + 2 * INT_SIZE) + print "mallocing %s, size %s at %s" % (typeid, size, result) + print "real size: %s" % (size + 2 * INT_SIZE, ) + result.signed[0] = 0 + result.signed[1] = typeid + self.malloced_objects.append(result) + self.bytes_malloced += size + 2 * INT_SIZE + return result + 2 * INT_SIZE + + def collect(self): + print "collecting" + self.bytes_malloced = 0 + roots = self.objectmodel.get_roots() + objects = AddressLinkedList() + while 1: + curr = roots.pop() + print "root: ", curr + if curr == NULL: + break + # roots is a list of addresses to addresses: + objects.append(curr.address[0]) + while 1: #mark + curr = objects.pop() + print "root: ", curr + if curr == NULL: + break + gc_info = curr - 2 * INT_SIZE + if gc_info.signed[0] == 1: + continue + pointers = self.objectmodel.get_contained_pointers( + curr, gc_info.signed[1]) + while 1: + pointer = pointers.pop() + if pointer == NULL: + break + objects.append(pointer) + gc_info.signed[0] = 1 + newmo = AddressLinkedList() + while 1: #sweep + curr = self.malloced_objects.pop() + if curr == NULL: + break + if curr.signed[0] == 1: + curr.signed[0] = 0 + newmo.append(curr) + else: + raw_free(curr) + free_non_gc_object(self.malloced_objects) + self.malloced_objects = newmo Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Thu Aug 11 20:36:14 2005 @@ -1,6 +1,10 @@ import py -from pypy.rpython.memory.gc import free_non_gc_object, GCError +from pypy.rpython.memory.gc import free_non_gc_object, GCError, MarkSweepGC +from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE +from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL +from pypy.rpython.memory.simulator import MemorySimulatorError + def test_free_non_gc_object(): class TestClass(object): @@ -21,3 +25,68 @@ py.test.raises(GCError, "t.method2()") py.test.raises(GCError, "t.a") py.test.raises(AssertionError, "free_non_gc_object(TestClass2())") + + +class PseudoObjectModel(object): + """Object model for testing purposes: you can specify roots and a + layout_mapping which is a dictionary of typeids to a list of offsets of + pointers in an object""" + def __init__(self, roots, layout_mapping): + self.roots = roots + self.layout_mapping = layout_mapping + + def get_roots(self): + self.roots + ll = AddressLinkedList() + for root in self.roots: + ll.append(root) + return ll + + def get_contained_pointers(self, addr, typeid): + if addr is NULL: + return AddressLinkedList() + layout = self.layout_mapping[typeid] + result = AddressLinkedList() + for offset in layout: + result.append(addr + offset) + return result + +class TestMarkSweepGC(object): + def test_simple(self): + variables = raw_malloc(4 * INT_SIZE) + roots = [variables + i * INT_SIZE for i in range(4)] + layout0 = [] #int + layout1 = [0, INT_SIZE] #(ptr, ptr) + om = PseudoObjectModel(roots, {0: layout0, 1: layout1}) + gc = MarkSweepGC(om, 2 ** 16) + variables.address[0] = gc.malloc(0, INT_SIZE) + variables.address[1] = gc.malloc(0, INT_SIZE) + variables.address[2] = gc.malloc(0, INT_SIZE) + variables.address[3] = gc.malloc(0, INT_SIZE) + print "roots", roots + gc.collect() #does not crash + addr = gc.malloc(0, INT_SIZE) + addr.signed[0] = 1 + print "roots", roots + gc.collect() + py.test.raises(MemorySimulatorError, "addr.signed[0]") + variables.address[0] = gc.malloc(1, 2 * INT_SIZE) + variables.address[0].address[0] = variables.address[1] + variables.address[0].address[1] = NULL + print "roots", roots + gc.collect() #does not crash + addr0 = gc.malloc(1, 2 * INT_SIZE) + addr0.address[1] = NULL + addr1 = gc.malloc(1, 2 * INT_SIZE) + addr1.address[0] = addr1.address[1] = NULL + addr0.address[0] = addr1 + addr2 = variables.address[1] + print "addr0, addr1, addr2 =", addr0, addr1, addr2 + variables.address[1] == NULL + variables.address[0].address[0] = NULL + print "roots", roots + gc.collect() + py.test.raises(MemorySimulatorError, "addr0.signed[0]") + py.test.raises(MemorySimulatorError, "addr1.signed[0]") + py.test.raises(MemorySimulatorError, "addr2.signed[0]") + From pedronis at codespeak.net Thu Aug 11 22:14:35 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 11 Aug 2005 22:14:35 +0200 (CEST) Subject: [pypy-svn] r15976 - pypy/dist/pypy/translator/goal Message-ID: <20050811201435.C0C2927B64@code1.codespeak.net> Author: pedronis Date: Thu Aug 11 22:14:34 2005 New Revision: 15976 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: fixing typo Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Thu Aug 11 22:14:34 2005 @@ -604,7 +604,7 @@ elif options['-no-c']: print 'Not generating C code.' elif options['-c']: - if option['-llvm']: + if options['-llvm']: print 'Generating LLVM code without compiling it...' filename = t.llvmcompile(really_compile=False, standalone=standalone) From cfbolz at codespeak.net Thu Aug 11 22:30:20 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 11 Aug 2005 22:30:20 +0200 (CEST) Subject: [pypy-svn] r15977 - in pypy/dist/pypy/rpython: . memory memory/test Message-ID: <20050811203020.36D8C27B64@code1.codespeak.net> Author: cfbolz Date: Thu Aug 11 22:30:19 2005 New Revision: 15977 Added: pypy/dist/pypy/rpython/memory/gcwrapper.py Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: first stab at integrating garbage collection in the llinterpreter. This is probably still quite flaky. At the moment only collectors that don't need read/write barriers are supported and collectors that need only the roots. I cheat in some places: the offsets in objects to pointers to other objects are found by using the searching through the lltype. this can be computed in advance, but isn't at the moment. This all is not very well tested yet :-(. I suspect that there are some bugs. I need to check in to change computers. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Aug 11 22:30:19 2005 @@ -19,6 +19,10 @@ def __init__(self, flowgraphs, typer, lltype=lltype, prepare_graphs=None): if prepare_graphs is not None: prepare_graphs(flowgraphs) + if hasattr(lltype, "create_gc"): + self.gc = lltype.create_gc(self) + else: + self.gc = None self.flowgraphs = flowgraphs self.bindings = {} self.typer = typer @@ -55,6 +59,17 @@ print " ", print operation + def find_roots(self): + print "find_roots" + frame = self.active_frame + roots = [] + while frame is not None: + print frame.graph.name + frame.find_roots(roots) + frame = frame.f_back + return roots + + # implementations of ops from flow.operation from pypy.objspace.flow.operation import FunctionByName opimpls = FunctionByName.copy() @@ -212,6 +227,16 @@ #print "GOT A CPYTHON EXCEPTION:", e.__class__, e self.make_llexception(e) + def find_roots(self, roots): + print "find_roots in LLFrame", roots, self.curr_block.inputargs + for arg in self.curr_block.inputargs: + if (isinstance(arg, Variable) and + isinstance(self.getval(arg), self.llt._ptr)): + roots.append(self.getval(arg)) + for op in self.curr_block.operations[:self.curr_operation_index]: + if isinstance(self.getval(op.result), self.llt._ptr): + roots.append(self.getval(op.result)) + # __________________________________________________________ # misc LL operation implementations @@ -249,7 +274,16 @@ return frame.eval() def op_malloc(self, obj): - return self.llt.malloc(obj) + if self.llinterpreter.gc is not None: + return self.llinterpreter.gc.malloc(obj) + else: + return self.llt.malloc(obj) + + def op_malloc_varsize(self, obj, size): + if self.llinterpreter.gc is not None: + return self.llinterpreter.gc.malloc(obj, size) + else: + return self.llt.malloc(obj, size) def op_getfield(self, obj, field): assert isinstance(obj, self.llt._ptr) @@ -269,9 +303,6 @@ self.llt.Ptr(getattr(self.llt.typeOf(obj).TO, field))) return result - def op_malloc_varsize(self, obj, size): - return self.llt.malloc(obj, size) - def op_getarraysubstruct(self, array, index): assert isinstance(array, self.llt._ptr) result = array[index] Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Aug 11 22:30:19 2005 @@ -54,9 +54,11 @@ break # roots is a list of addresses to addresses: objects.append(curr.address[0]) + gc_info = curr.address[0] - 2 * INT_SIZE + assert gc_info.signed[0] == 0 while 1: #mark curr = objects.pop() - print "root: ", curr + print "object: ", curr if curr == NULL: break gc_info = curr - 2 * INT_SIZE Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Thu Aug 11 22:30:19 2005 @@ -21,7 +21,7 @@ # the following names from lltype will probably have to be implemented yet: -# opaqueptr, pyobjectptr, attachRuntimeTypeInfo, getRuntimeTypeInfo, +# opaqueptr, attachRuntimeTypeInfo, getRuntimeTypeInfo, # runtime_type_info opaqueptr = attachRuntimeTypeInfo = notimplemented @@ -34,3 +34,16 @@ fgcc = FlowGraphConstantConverter(flowgraphs) fgcc.convert() +def create_no_gc(llinterp): + return None + +def create_mark_sweep_gc(llinterp): + from pypy.rpython.memory.gcwrapper import GcWrapper, LLInterpObjectModel + from pypy.rpython.memory.gc import MarkSweepGC + om = LLInterpObjectModel(llinterp) + gc = MarkSweepGC(om, 4096) + wrapper = GcWrapper(llinterp, gc) + return wrapper + +create_gc = create_no_gc + Added: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Thu Aug 11 22:30:19 2005 @@ -0,0 +1,102 @@ +from pypy.rpython import lltype +from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE +from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL +from pypy.rpython.memory import lltypesimulation +from pypy.rpython.memory.gc import MarkSweepGC + +class LLInterpObjectModel(object): + def __init__(self, llinterp): + self.type_to_typeid = {} + self.types = [] + self.roots = [] + self.pseudo_root_pointers = NULL + self.llinterp = llinterp + + def update_changed_addresses(self): + for i, root in enumerate(self.roots): + if root._address != self.pseudo_root_pointers.address[i]: + print "address changed:", root._address, self.pseudo_root_pointers.address[i] + root.__dict__['_address'] = self.pseudo_root_pointers.address[i] + + def get_typeid(self, TYPE): + if TYPE not in self.type_to_typeid: + index = len(self.types) + self.type_to_typeid[TYPE] = index + self.types.append(TYPE) + typeid = self.type_to_typeid[TYPE] + return typeid + + def get_roots(self): + print "getting roots" + if self.pseudo_root_pointers != NULL: + raw_free(self.pseudo_root_pointers) + self.roots = self.llinterp.find_roots() + print "found:", self.roots + self.pseudo_root_pointers = raw_malloc(len(self.roots) * INT_SIZE) + ll = AddressLinkedList() + for i, root in enumerate(self.roots): + self.pseudo_root_pointers.address[i] = root._address + ll.append(self.pseudo_root_pointers + INT_SIZE * i) + return ll + + def get_contained_pointers(self, addr, typeid): + TYPE = self.types[typeid] + if isinstance(TYPE, lltype.Struct): + offsets = self.get_contained_pointers_struct(addr, TYPE) + elif isinstance(TYPE, lltype.Array): + offsets = self.get_contained_pointers_array(addr, TYPE) + ll = AddressLinkedList() + for offset in offsets: + ll.append(addr + offset) + print "for the TYPE %s if found the follwing offsets: %s" % (TYPE, offsets) + return ll + + def get_contained_pointers_struct(self, addr, TYPE, offset=0): + offsets = [] + substructures = [(TYPE, offset)] + while len(substructures): + TYPE, offset = substructures.pop() + layout = lltypesimulation.get_layout(TYPE) + for name in TYPE._names: + FIELD = getattr(TYPE, name) + if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc(): + offsets.append(offset + layout[name]) + elif isinstance(FIELD, lltype.Struct): + substructures.append((FIELD, layout[name] + offset)) + elif isinstance(FIELD, lltype.Array): + assert offset == 0 #can only inline into outermost struct + baseaddr = addr + layout[name] + offsets += self.get_contained_pointers_array( + baseaddr, FIELD, layout[name]) + return offsets + + def get_contained_pointers_array(self, addr, TYPE, offset=0): + offsets = [] + length = addr.signed[0] + itemsize = lltypesimulation.get_variable_size(TYPE) + if isinstance(TYPE.OF, lltype.Ptr) and TYPE.OF._needsgc(): + for i in range(length): + offsets.append(offset + INT_SIZE + i * itemsize) + elif isinstance(TYPE.OF, lltype.GcStruct): + for i in range(length): + item_offset = INT_SIZE + i * itemsize + offsets += self.get_contained_pointers_array( + TYPE.OF, addr + item_offset, offset + item_offset) + return offsets + +class GcWrapper(object): + def __init__(self, llinterp, gc): + self.llinterp = llinterp + self.objectmodel = gc.objectmodel + assert isinstance(self.objectmodel, LLInterpObjectModel) + self.gc = gc + + def malloc(self, TYPE, size=0): + typeid = self.objectmodel.get_typeid(TYPE) + address = self.gc.malloc(typeid, + lltypesimulation.get_total_size(TYPE, size)) + result = lltypesimulation.simulatorptr(lltype.Ptr(TYPE), address) + result._zero_initialize(size) + result._init_size(size) + self.objectmodel.update_changed_addresses() + return result Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Thu Aug 11 22:30:19 2005 @@ -386,22 +386,19 @@ assert ''.join(res.chars) == '-123' -#__________________________________________________________________ -# interactive playing - -if __name__ == '__main__': - try: - import rlcompleter2 as _rl2 - _rl2.setup() - except ImportError: - pass - - t, typer = gengraph(number_ops, [int]) - interp = LLInterpreter(t.flowgraphs, typer) - res = interp.eval_function(number_ops, [3]) - assert res == number_ops(3) - for name, value in globals().items(): - if name not in _snap and name[0] != '_': - print "%20s: %s" %(name, value) - - +def test_mark_sweep_gc(): + from pypy.rpython.memory.lladdress import simulator + gclltype.create_gc = gclltype.create_mark_sweep_gc + curr = simulator.current_size + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = [1] * 10 + j = 0 + while j < 20: + j += 1 + a.append(j) + res = interpret(malloc_a_lot, []) + assert simulator.current_size - curr < 16000 + print "size before: %s, size after %s" % (curr, simulator.current_size) From rxe at codespeak.net Thu Aug 11 23:42:56 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 11 Aug 2005 23:42:56 +0200 (CEST) Subject: [pypy-svn] r15981 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050811214256.D8EFC27B64@code1.codespeak.net> Author: rxe Date: Thu Aug 11 23:42:54 2005 New Revision: 15981 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/test/test_lltype.py Log: remove embedexterns and work a little on readability. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 11 23:42:54 2005 @@ -24,14 +24,12 @@ class GenLLVM(object): - def __init__(self, translator, debug=False, embedexterns=True): - embedexterns = True # XXX just for now because exception handling globals must be available + def __init__(self, translator, debug=False): # reset counters LLVMNode.nodename_count = {} self.db = Database(translator) self.translator = translator - self.embedexterns = embedexterns translator.checkgraphs() ExternalFuncNode.used_external_functions = {} @@ -100,9 +98,8 @@ if self.debug: print 'gen_llvm_source extdeclarations) ' + time.ctime() nl(); comment("Function Prototypes") ; nl() - if self.embedexterns: - for extdecl in extdeclarations.split('\n'): - codewriter.append(extdecl) + for extdecl in extdeclarations.split('\n'): + codewriter.append(extdecl) if self.debug: print 'gen_llvm_source self._debug_prototype) ' + time.ctime() if self.debug: @@ -178,26 +175,39 @@ if self.debug: print 'gen_llvm_source return) ' + time.ctime() return filename - def create_module(self, filename, really_compile=True, standalone=False, optimize=True, exe_name=None): - if not llvm_is_on_path(): - py.test.skip("llvm not found") # XXX not good to call py.test.skip here + def create_module(self, + filename, + really_compile=True, + standalone=False, + optimize=True, + exe_name=None): + + if not llvm_is_on_path(): + # XXX not good to call py.test.skip here + py.test.skip("llvm not found") if standalone: - return build_llvm_module.make_module_from_llvm(filename, optimize=optimize, exe_name=exe_name) + return build_llvm_module.make_module_from_llvm(filename, + optimize=optimize, + exe_name=exe_name) else: postfix = '' - pyxfile = filename.new(basename=filename.purebasename+'_wrapper'+postfix+'.pyx') + basename = filename.purebasename+'_wrapper'+postfix+'.pyx' + pyxfile = filename.new(basename = basename) write_pyx_wrapper(self.entrynode, pyxfile) - return build_llvm_module.make_module_from_llvm(filename, pyxfile=pyxfile, optimize=optimize) + return build_llvm_module.make_module_from_llvm(filename, + pyxfile=pyxfile, + optimize=optimize) def _debug_prototype(self, codewriter): codewriter.append("declare int %printf(sbyte*, ...)") -def genllvm(translator, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): - gen = GenLLVM(translator, embedexterns=embedexterns) +def genllvm(translator, log_source=False, **kwds): + gen = GenLLVM(translator) filename = gen.gen_llvm_source() - #log.genllvm(open(filename).read()) - return gen.create_module(filename, really_compile=really_compile, standalone=standalone, optimize=optimize, exe_name=exe_name) + if log_source: + log.genllvm(open(filename).read()) + return gen.create_module(filename, **kwds) def llvm_is_on_path(): try: @@ -206,19 +216,19 @@ return False return True -def compile_module(function, annotation, view=False, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): +def compile_module(function, annotation, view=False, **kwds): t = Translator(function) a = t.annotate(annotation) t.specialize() if view: t.view() - return genllvm(t, really_compile=really_compile, standalone=standalone, optimize=optimize, embedexterns=embedexterns, exe_name=exe_name) + return genllvm(t, **kwds) -def compile_function(function, annotation, view=False, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): - mod = compile_module(function, annotation, view=view, really_compile=really_compile, standalone=standalone, optimize=optimize, embedexterns=embedexterns, exe_name=exe_name) +def compile_function(function, annotation, **kwds): + mod = compile_module(function, annotation) return getattr(mod, function.func_name + "_wrapper") -def compile_module_function(function, annotation, view=False, really_compile=True, standalone=False, optimize=True, embedexterns=True, exe_name=None): - mod = compile_module(function, annotation, view=view, really_compile=really_compile, standalone=standalone, optimize=optimize, embedexterns=embedexterns, exe_name=exe_name) +def compile_module_function(function, annotation, **kwds): + mod = compile_module(function, annotation, **kwds) f = getattr(mod, function.func_name + "_wrapper") return mod, f Modified: pypy/dist/pypy/translator/llvm2/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_lltype.py Thu Aug 11 23:42:54 2005 @@ -28,7 +28,7 @@ def struct_constant(): x1 = s.signed + s.unsigned return x1 - f = compile_function(struct_constant, [], embedexterns=False) + f = compile_function(struct_constant, []) assert f() == struct_constant() def test_struct_constant2(): @@ -41,7 +41,7 @@ s.s2.b = 3 def struct_constant(): return s.a + s.s2.b + s.s1.a + s.s1.b - f = compile_function(struct_constant, [], embedexterns=False) + f = compile_function(struct_constant, []) assert f() == struct_constant() def test_struct_constant3(): @@ -62,7 +62,7 @@ return (top.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.a - top.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.s.b) - f = compile_function(struct_constant, [], embedexterns=False) + f = compile_function(struct_constant, []) assert f() == struct_constant() def test_struct_constant4(): @@ -73,7 +73,7 @@ s.sptr.a = 21 def struct_constant(): return s.sptr.a * 2 - f = compile_function(struct_constant, [], embedexterns=False) + f = compile_function(struct_constant, []) assert f() == struct_constant() def test_struct_constant5(): @@ -86,7 +86,7 @@ s.sptr.b.b = 10 def struct_constant(): return s.sptr.a + s.sptr.b.a + s.sptr.b.b - f = compile_function(struct_constant, [], embedexterns=False) + f = compile_function(struct_constant, []) assert f() == struct_constant() def test_struct_constant6(): @@ -101,7 +101,7 @@ s.p = s.u def struct_constant(): return s.x.y + s.p.z - f = compile_function(struct_constant, [], embedexterns=False) + f = compile_function(struct_constant, []) assert f() == struct_constant() def test_aliasing(): @@ -112,7 +112,7 @@ def aliasing(i): global_b.x = 17 return global_a[i].x - f = compile_function(aliasing, [int], embedexterns=False) + f = compile_function(aliasing, [int]) assert f(2) == 0 assert f(3) == 17 @@ -126,7 +126,7 @@ def aliasing(i): global_c.bptr.x = 17 return global_a[i].x - f = compile_function(aliasing, [int], embedexterns=False) + f = compile_function(aliasing, [int]) assert f(2) == 0 assert f(3) == 17 @@ -138,7 +138,7 @@ a[2] = 102 def array_constant(): return a[0] + a[1] + a[2] - f = compile_function(array_constant, [], embedexterns=False) + f = compile_function(array_constant, []) assert f() == array_constant() def test_array_constant2(): @@ -150,7 +150,7 @@ def array_constant(): a[0] = 0 return a[0] + a[1] + a[2] - f = compile_function(array_constant, [], embedexterns=False) + f = compile_function(array_constant, []) assert f() == array_constant() def test_array_constant3(): @@ -161,7 +161,7 @@ a[2].x = 102 def array_constant(): return a[0].x + a[1].x + a[2].x - f = compile_function(array_constant, [], embedexterns=False) + f = compile_function(array_constant, []) assert f() == array_constant() def test_struct_array1(): @@ -173,7 +173,7 @@ a[1] = 101 def array_constant(): return s.aptr[1] - a[0] - f = compile_function(array_constant, [], embedexterns=False) + f = compile_function(array_constant, []) assert f() == array_constant() def test_struct_array2(): @@ -185,7 +185,7 @@ s.b[1] = 101 def array_constant(): return s.b[1] - s.b[0] + s.a - f = compile_function(array_constant, [], embedexterns=False) + f = compile_function(array_constant, []) assert f() == array_constant() def test_struct_array3(): @@ -201,7 +201,7 @@ def array_constant(): s = b.p return s.b[1] - s.b[0] + s.a - f = compile_function(array_constant, [], embedexterns=False) + f = compile_function(array_constant, []) assert f() == array_constant() def test_struct_opaque(): @@ -211,5 +211,5 @@ s.a = 42 def array_constant(): return s.a - f = compile_function(array_constant, [], embedexterns=False) + f = compile_function(array_constant, []) assert f() == array_constant() From pedronis at codespeak.net Fri Aug 12 00:40:51 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 12 Aug 2005 00:40:51 +0200 (CEST) Subject: [pypy-svn] r15986 - pypy/dist/pypy/translator/c/src Message-ID: <20050811224051.0E14327B64@code1.codespeak.net> Author: pedronis Date: Fri Aug 12 00:40:50 2005 New Revision: 15986 Modified: pypy/dist/pypy/translator/c/src/ll_math.h Log: one space too much Modified: pypy/dist/pypy/translator/c/src/ll_math.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_math.h (original) +++ pypy/dist/pypy/translator/c/src/ll_math.h Fri Aug 12 00:40:50 2005 @@ -24,7 +24,7 @@ #define LL_MATH_ERROR_RESET errno = 0 -#define LL_MATH_CHECK_ERROR(x, errret) do { \ +#define LL_MATH_CHECK_ERROR(x, errret) do { \ LL_MATH_SET_ERANGE_IF_MATH_ERROR(x); \ if (errno && ll_math_is_error(x)) \ return errret; \ From pedronis at codespeak.net Fri Aug 12 00:53:06 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 12 Aug 2005 00:53:06 +0200 (CEST) Subject: [pypy-svn] r15987 - pypy/dist/pypy/translator/c/test Message-ID: <20050811225306.BAF9227B64@code1.codespeak.net> Author: pedronis Date: Fri Aug 12 00:53:05 2005 New Revision: 15987 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: oops, make the test a bit more robust against platform/math lib differences (e.g. the test was failing on PPC/Mac OS X) Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Fri Aug 12 00:53:05 2005 @@ -202,13 +202,30 @@ return math.log(x) f = compile(fn, [float]) assert f(math.e) == math.log(math.e) - py.test.raises(ValueError, f, -1.0) - py.test.raises(OverflowError, f, 0.0) - import math - def fn(y): + # 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(fn, [float]) - py.test.raises(ValueError, f, 0.0) + f = compile(fmod1_0, [float]) + check(fmod1_0, f, 0.0) def test_os_path_exists(): From rxe at codespeak.net Fri Aug 12 01:23:57 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 12 Aug 2005 01:23:57 +0200 (CEST) Subject: [pypy-svn] r15992 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050811232357.5E58B27B64@code1.codespeak.net> Author: rxe Date: Fri Aug 12 01:23:56 2005 New Revision: 15992 Modified: pypy/dist/pypy/translator/llvm2/module/support.py Log: rpy_string s are already null terminated (sorry but was causing problems on 64 bit machine and since we dont need it, better to get rid of it than fix it. Also it's an optimisation. :-) Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 12 01:23:56 2005 @@ -8,22 +8,9 @@ extfunctions["%cast"] = ((), """ internal fastcc sbyte* %cast(%structtype.rpy_string* %structstring) { - %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 - %reallength = load int* %reallengthptr - %length = add int %reallength, 1 - %ulength = cast int %length to uint - %dest = call fastcc sbyte* %gc_malloc_atomic(uint %ulength) - %source1ptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 1 %source1 = cast [0 x sbyte]* %source1ptr to sbyte* - %dummy = call ccc sbyte* %strncpy(sbyte* %dest, sbyte* %source1, int %reallength) - - %zeropos1 = cast sbyte* %dest to int - %zeropos2 = add int %zeropos1, %reallength - %zerodest = cast int %zeropos2 to sbyte* - store sbyte 0, sbyte* %zerodest - - ret sbyte* %dest + ret sbyte* %source1 } """) From rxe at codespeak.net Fri Aug 12 01:31:57 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 12 Aug 2005 01:31:57 +0200 (CEST) Subject: [pypy-svn] r15993 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050811233157.CF21F27B64@code1.codespeak.net> Author: rxe Date: Fri Aug 12 01:31:53 2005 New Revision: 15993 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/node.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/pyxwrapper.py pypy/dist/pypy/translator/llvm2/structnode.py pypy/dist/pypy/translator/llvm2/varsize.py Log: A first attempt at getting genllvm2 to work on 64 bit machines. Not everything is working... yet. Mostly externals and some exceptions (ones that involve external code); this is another reason why we should at least aim to generate the code instead of hand-coding it - I guess. But we know that! Also in this checkin: * Annotated some commented out code with XXX and reasons * Got rid of some horrendously long and unreabable names of generated ArrayTypeNodes Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Fri Aug 12 01:31:53 2005 @@ -14,17 +14,28 @@ self.db = db self.array = array - self.arraytype = array.OF + arraytype = self.arraytype = array.OF # ref is used to reference the arraytype in llvm source # constructor_ref is used to reference the constructor # for the array type in llvm source code # constructor_decl is used to declare the constructor # for the array type (see writeimpl) c = nextnum() - self.ref = "%%arraytype.%s.%s" % (c, self.arraytype) - self.constructor_ref = "%%new.array.%s" % c - self.constructor_decl = "%s * %s(int %%len)" % \ - (self.ref, self.constructor_ref) + name = "" + if isinstance(arraytype, lltype.Ptr): + name += "ptr_" + arraytype = arraytype.TO + if hasattr(arraytype, "_name"): + name += arraytype._name + else: + name += str(arraytype) + + self.ref = self.make_ref('%arraytype.', name) + self.constructor_ref = self.make_ref('%new.array.', name) + self.constructor_decl = "%s * %s(%s %%len)" % \ + (self.ref, + self.constructor_ref, + self.db.get_machine_word()) def __str__(self): return "" % self.ref @@ -45,7 +56,9 @@ # entry points from genllvm # def writedatatypedecl(self, codewriter): - codewriter.arraydef(self.ref, self.db.repr_arg_type(self.arraytype)) + codewriter.arraydef(self.ref, + self.db.get_machine_word(), + self.db.repr_arg_type(self.arraytype)) def writedecl(self, codewriter): # declaration for constructor @@ -54,7 +67,7 @@ def writeimpl(self, codewriter): log.writeimpl(self.ref) fromtype = self.db.repr_arg_type(self.arraytype) - varsize.write_constructor(codewriter, self.ref, + varsize.write_constructor(self.db, codewriter, self.ref, self.constructor_decl, fromtype, atomicmalloc=self.is_atomic()) @@ -63,10 +76,11 @@ def __init__(self, db, array): assert isinstance(array, lltype.Array) + self.db = db self.ref = "%arraytype.Void" def writedatatypedecl(self, codewriter): - td = "%s = type { int }" % self.ref + td = "%s = type { %s }" % (self.ref, self.db.get_machine_word()) codewriter.append(td) class ArrayNode(ConstantLLVMNode): @@ -108,7 +122,8 @@ def get_typerepr(self): arraylen = self.get_arrayvalue()[0] typeval = self.db.repr_arg_type(self.arraytype) - return "{ int, [%s x %s] }" % (arraylen, typeval) + return "{ %s, [%s x %s] }" % (self.db.get_machine_word(), + arraylen, typeval) def get_ref(self): typeval = self.db.repr_arg_type(lltype.typeOf(self.value)) @@ -145,10 +160,11 @@ typeval = self.db.repr_arg_type(self.arraytype) # first length is logical, second is physical - value = "int %s, [%s x %s] %s" % (self.get_length(), - physicallen, - typeval, - arrayrepr) + value = "%s %s, [%s x %s] %s" % (self.db.get_machine_word(), + self.get_length(), + physicallen, + typeval, + arrayrepr) s = "%s {%s}" % (self.get_typerepr(), value) return s @@ -164,15 +180,6 @@ item_length = len(items) if item_length == 0 or items[-1] != chr(0): items = items + [chr(0)] - l = item_length + 1 - r = "".join([self.db.repr_constant(v)[1] for v in items]) - return l, r - - def get_arrayvalue(self): - items = self.value.items - item_length = len(items) - if item_length == 0 or items[-1] != chr(0): - items = items + [chr(0)] item_length += 1 s = [] for c in items: @@ -188,9 +195,12 @@ def __init__(self, db, value): assert isinstance(lltype.typeOf(value), lltype.Array) + self.db = db self.ref = self.make_ref('%arrayinstance', '') self.value = value def constantvalue(self): - return "{ int } {int %s}" % len(self.value.items) + return "{ %s } {%s %s}" % (self.db.get_machine_word(), + self.db.get_machine_word(), + len(self.value.items)) Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Fri Aug 12 01:31:53 2005 @@ -41,8 +41,8 @@ def structdef(self, name, typereprs): self.append("%s = type { %s }" %(name, ", ".join(typereprs))) - def arraydef(self, name, typerepr): - self.append("%s = type { int, [0 x %s] }" % (name, typerepr)) + def arraydef(self, name, lentype, typerepr): + self.append("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr)) def funcdef(self, name, rettyperepr, argtypereprs): self.append("%s = type %s (%s)" % (name, rettyperepr, Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Fri Aug 12 01:31:53 2005 @@ -1,3 +1,4 @@ +import sys from pypy.translator.llvm2.log import log from pypy.translator.llvm2.funcnode import FuncNode, FuncTypeNode from pypy.translator.llvm2.extfuncnode import ExternalFuncNode @@ -13,14 +14,6 @@ log = log.database -PRIMITIVES_TO_LLVM = {lltype.Signed: "int", - lltype.Char: "sbyte", - lltype.Unsigned: "uint", - lltype.Bool: "bool", - lltype.Float: "double", - lltype.UniChar: "uint", - lltype.Void: "void"} - class NormalizingDict(object): """ this is a helper dict for obj2node in order to allow saner key-unification for Ptrs to functions @@ -60,17 +53,6 @@ def items(self): return self._dict.items() -def primitive_to_str(type_, value): - if type_ is lltype.Bool: - repr = str(value).lower() #False --> false - elif type_ is lltype.Char: - repr = str(ord(value)) - elif type_ is lltype.UniChar: - repr = str(ord(value)) - else: - repr = str(value) - return repr - class Database(object): def __init__(self, translator): self._translator = translator @@ -81,6 +63,33 @@ # debug operation comments self._opcomments = {} + self.primitives_init() + + def primitives_init(self): + primitives = { + lltype.Char: "sbyte", + lltype.Bool: "bool", + lltype.Float: "double", + lltype.UniChar: "uint", + lltype.Void: "void"} + + # 32 bit platform + if sys.maxint == 2**31-1: + primitives.update({ + lltype.Signed: "int", + lltype.Unsigned: "uint" }) + + # 64 bit platform + elif sys.maxint == 2**63-1: + primitives.update({ + lltype.Signed: "long", + lltype.Unsigned: "ulong" }) + + else: + assert False, "Unsupported platform" + + self.primitives = primitives + #_______for debugging llvm code_________________________ def add_op2comment(self, lenofopstr, op): @@ -270,11 +279,11 @@ # __________________________________________________________ # Representing variables and constants in LLVM source code - + def repr_arg(self, arg): if isinstance(arg, Constant): if isinstance(arg.concretetype, lltype.Primitive): - return primitive_to_str(arg.concretetype, arg.value) + return self.primitive_to_str(arg.concretetype, arg.value) else: node = self.obj2node.get(arg) if node is None: @@ -292,7 +301,7 @@ return self.obj2node[arg].ref except KeyError: if isinstance(arg, lltype.Primitive): - return PRIMITIVES_TO_LLVM[arg] + return self.primitives[arg] elif isinstance(arg, lltype.Ptr): return self.repr_arg_type(arg.TO) + '*' else: @@ -311,7 +320,7 @@ " returns node and repr as tuple " type_ = lltype.typeOf(value) if isinstance(type_, lltype.Primitive): - repr = primitive_to_str(type_, value) + repr = self.primitive_to_str(type_, value) return None, "%s %s" % (self.repr_arg_type(type_), repr) elif isinstance(type_, lltype.Ptr): @@ -336,3 +345,24 @@ count = self._tmpcount self._tmpcount += 1 return "%tmp." + str(count) + + # __________________________________________________________ + # Primitive stuff + + def primitive_to_str(self, type_, value): + #XXX Need to watch for special float values (inf, 2E200) + if type_ is lltype.Bool: + repr = str(value).lower() #False --> false + elif type_ is lltype.Char: + repr = str(ord(value)) + elif type_ is lltype.UniChar: + repr = str(ord(value)) + else: + repr = str(value) + return repr + + def get_machine_word(self): + return self.primitives[lltype.Signed] + + def get_machine_uword(self): + return self.primitives[lltype.Unsigned] Modified: pypy/dist/pypy/translator/llvm2/node.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/node.py (original) +++ pypy/dist/pypy/translator/llvm2/node.py Fri Aug 12 01:31:53 2005 @@ -35,7 +35,7 @@ if hasattr(self, "_constructor_ref"): raise TypeError, ("can only set constructor_ref once!" " currently: %s" % (self._constructor_ref,)) - if " " in ref: + if " " in ref or "<" in ref: ref = '"%s"' % (ref,) self._constructor_ref = ref return property(_get_ref, _set_ref) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Fri Aug 12 01:31:53 2005 @@ -96,6 +96,7 @@ if not meth: msg = "operation %s not found" %(op.opname,) self.codewriter.comment('XXX: Error: ' + msg) + # XXX commented out for testing #assert meth is not None, msg return meth(op) @@ -105,9 +106,12 @@ mult_val = self.db.repr_arg(op.args[0]) last_val = mult_val try: - operand = int(op.args[1].value) - except: - msg = 'XXX: Error: _generic_pow: Variable has no value' + value = "NO VALUE" + value = op.args[1].value + operand = int(value) + except Exception, exc: + msg = 'XXX: Error: _generic_pow: Variable '\ + '%s - failed to convert to int %s' % (value, str(exc)) self.codewriter.comment(msg) return if operand < 1: @@ -150,8 +154,11 @@ self.db.repr_arg(op.args[0]), ) def int_neg(self, op): - self._generic_neg(op, "0") - uint_neg = int_neg #this is really generates, don't know why + self._generic_neg(op, "0") + + #this is really generated, don't know why + # XXX rxe: Surely that cant be right? + uint_neg = int_neg def float_neg(self, op): self._generic_neg(op, "0.0") @@ -200,7 +207,8 @@ self.db.repr_arg(op.args[0]), tmpvar) - def cast_primitive(self, op): #works for all primitives + def cast_primitive(self, op): + " works for all casts " assert len(op.args) == 1 targetvar = self.db.repr_arg(op.result) targettype = self.db.repr_arg_type(op.result) @@ -256,7 +264,6 @@ self.codewriter.call_void(functionref, argrefs, argtypes) def invoke(self, op): - # XXX hack as per remove_voids() op_args = [arg for arg in op.args if arg.concretetype is not lltype.Void] @@ -271,6 +278,7 @@ else: msg = "exception raising operation %s not found" %(op.opname,) self.codewriter.comment('XXX: Error: ' + msg) + # XXX commented out for testing #assert functionref in extfunctions, msg assert len(op_args) >= 1 @@ -416,7 +424,9 @@ ("uint", index)) self.codewriter.load(targetvar, targettype, tmpvar) else: - self.codewriter.comment("***Skipping operation getfield()***") #XXX what if this the last operation of the exception block? + #XXX what if this the last operation of the exception block? + # XXX rxe: would a getfield() ever raise anyway??? + self.codewriter.comment("***Skipping operation getfield()***") def getsubstruct(self, op): struct, structtype = self.db.repr_argwithtype(op.args[0]) @@ -470,7 +480,6 @@ valuevar = self.db.repr_arg(op.args[2]) valuetype = self.db.repr_arg_type(op.args[2]) - #XXX These should skip too if the case comes up if valuetype != "void": self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 1), (indextype, index)) @@ -478,7 +487,6 @@ else: self.codewriter.comment("***Skipping operation setarrayitem()***") - def getarraysize(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) tmpvar = self.db.repr_tmpvar() Modified: pypy/dist/pypy/translator/llvm2/pyxwrapper.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/pyxwrapper.py (original) +++ pypy/dist/pypy/translator/llvm2/pyxwrapper.py Fri Aug 12 01:31:53 2005 @@ -1,15 +1,29 @@ +import sys from pypy.translator.llvm2.log import log from pypy.rpython import lltype from pypy.translator.llvm2.genllvm import use_boehm_gc log = log.pyrex -PRIMITIVES_TO_C = {lltype.Signed: "int", - lltype.Unsigned: "unsigned int", - lltype.Bool: "char", +PRIMITIVES_TO_C = {lltype.Bool: "char", lltype.Float: "double", lltype.Char: "char", } +# 32 bit platform +if sys.maxint == 2**31-1: + PRIMITIVES_TO_C.update({ + lltype.Signed: "int", + lltype.Unsigned: "unsigned int" }) + +# 64 bit platform +elif sys.maxint == 2**63-1: + PRIMITIVES_TO_C.update({ + lltype.Signed: "long", + lltype.Unsigned: "unsigned long" }) + +else: + assert False, "Unsupported platform" + def write_pyx_wrapper(funcgen, targetpath): def c_declaration(): returntype = PRIMITIVES_TO_C[ Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Fri Aug 12 01:31:53 2005 @@ -51,8 +51,10 @@ def __init__(self, db, struct): super(StructVarsizeTypeNode, self).__init__(db, struct) self.constructor_ref = "%%new.varsizestruct.%s" % (self.name) - self.constructor_decl = "%s * %s(int %%len)" % \ - (self.ref, self.constructor_ref) + self.constructor_decl = "%s * %s(%s %%len)" % \ + (self.ref, + self.constructor_ref, + self.db.get_machine_word()) def __str__(self): return "" %(self.ref,) @@ -79,7 +81,7 @@ assert isinstance(current, lltype.Array) arraytype = self.db.repr_arg_type(current.OF) # XXX write type info as a comment - varsize.write_constructor(codewriter, + varsize.write_constructor(self.db, codewriter, self.ref, self.constructor_decl, arraytype, indices_to_array, atomicmalloc=self.is_atomic()) Modified: pypy/dist/pypy/translator/llvm2/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/varsize.py (original) +++ pypy/dist/pypy/translator/llvm2/varsize.py Fri Aug 12 01:31:53 2005 @@ -15,14 +15,15 @@ ret %array* %result }""" -def write_constructor(codewriter, ref, constructor_decl, elemtype, +def write_constructor(db, codewriter, ref, constructor_decl, elemtype, indices_to_array=(), atomicmalloc=False): #varsized arrays and structs look like this: #Array: {int length , elemtype*} #Struct: {...., Array} - # the following indices access the last element in the array - elemindices = list(indices_to_array) + [("uint", 1), ("int", "%len")] + # the following indices access the last element in the array + lentype = db.get_machine_word() + elemindices = list(indices_to_array) + [("uint", 1), (lentype, "%len")] codewriter.openfunc(constructor_decl) codewriter.getelementptr("%size", ref + "*", "null", *elemindices) @@ -35,7 +36,7 @@ codewriter.getelementptr("%arraylength", ref + "*", "%result", *indices_to_array) - codewriter.store("int", "%len", "%arraylength") + codewriter.store(lentype, "%len", "%arraylength") codewriter.ret(ref + "*", "%result") codewriter.closefunc() From pedronis at codespeak.net Fri Aug 12 02:36:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 12 Aug 2005 02:36:28 +0200 (CEST) Subject: [pypy-svn] r15994 - pypy/dist/pypy/translator/c Message-ID: <20050812003628.7EF1727B64@code1.codespeak.net> Author: pedronis Date: Fri Aug 12 02:36:24 2005 New Revision: 15994 Modified: pypy/dist/pypy/translator/c/external.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/support.py Log: slottify principal container nodes and func generators. translate_pypy mem usage with this for generating PyPy C code: 355mb down from 534mb USESLOTS flag to control this in support.py Modified: pypy/dist/pypy/translator/c/external.py ============================================================================== --- pypy/dist/pypy/translator/c/external.py (original) +++ pypy/dist/pypy/translator/c/external.py Fri Aug 12 02:36:24 2005 @@ -1,9 +1,12 @@ from __future__ import generators from pypy.rpython.lltype import typeOf, Void +from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring from pypy.translator.c.support import cdecl, ErrorValue, somelettersfrom -class CExternalFunctionCodeGenerator: +class CExternalFunctionCodeGenerator(object): + if USESLOTS: + __slots__ = """db fnptr FUNCTYPE argtypenames resulttypename""".split() def __init__(self, fnptr, db): self.fnptr = fnptr @@ -20,6 +23,9 @@ def allconstantvalues(self): return [] + def implementation_begin(self): + pass + def cfunction_declarations(self): if self.FUNCTYPE.RESULT != Void: yield '%s;' % cdecl(self.resulttypename, 'result') @@ -33,3 +39,8 @@ else: yield '%s;' % call yield 'if (PyErr_Occurred()) RPyConvertExceptionFromCPython();' + + def implementation_end(self): + pass + +assert not USESLOTS or '__dict__' not in dir(CExternalFunctionCodeGenerator) Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Fri Aug 12 02:36:24 2005 @@ -1,4 +1,5 @@ from __future__ import generators +from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring from pypy.translator.c.support import cdecl, ErrorValue from pypy.translator.c.support import llvalue_from_constant, gen_assignments from pypy.objspace.flow.model import Variable, Constant, Block @@ -10,12 +11,19 @@ PyObjPtr = Ptr(PyObject) LOCALVAR = 'l_%s' -class FunctionCodeGenerator: +class FunctionCodeGenerator(object): """ Collects information about a function which we have to generate from a flow graph. """ + if USESLOTS: + __slots__ = """graph db + cpython_exc + more_ll_values + vars + lltypes""".split() + def __init__(self, graph, db, cpython_exc=False): self.graph = graph self.db = db @@ -44,39 +52,49 @@ traverse(visit, graph) resultvar = graph.getreturnvar() + self.vars = mix + self.lltypes = None + for v in self.vars: + T = getattr(v, 'concretetype', PyObjPtr) + db.gettype(T) + + def implementation_begin(self): + db = self.db + resultvar = self.graph.getreturnvar() self.lltypes = { # default, normally overridden: - id(resultvar): (resultvar, Void, db.gettype(Void)), + id(resultvar): (Void, db.gettype(Void)), } - for v in mix: + for v in self.vars: T = getattr(v, 'concretetype', PyObjPtr) typename = db.gettype(T) - self.lltypes[id(v)] = v, T, typename + self.lltypes[id(v)] = T, typename + + def implementation_end(self): + self.lltypes = None def argnames(self): return [LOCALVAR % v.name for v in self.graph.getargs()] def allvariables(self): - return [v for v, T, typename in self.lltypes.values() - if isinstance(v, Variable)] + return [v for v in self.vars if isinstance(v, Variable)] def allconstants(self): - return [c for c, T, typename in self.lltypes.values() - if isinstance(c, Constant)] + return [c for c in self.vars if isinstance(c, Constant)] def allconstantvalues(self): - for c, T, typename in self.lltypes.values(): + for c in self.vars: if isinstance(c, Constant): yield llvalue_from_constant(c) for llvalue in self.more_ll_values: yield llvalue def lltypemap(self, v): - v, T, typename = self.lltypes[id(v)] + T, typename = self.lltypes[id(v)] return T def lltypename(self, v): - v, T, typename = self.lltypes[id(v)] + T, typename = self.lltypes[id(v)] return typename def expr(self, v, special_case_void=True): @@ -530,3 +548,5 @@ def cdecref(self, v, expr=None): T = self.lltypemap(v) return self.db.cdecrefstmt(expr or (LOCALVAR % v.name), T) + +assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Fri Aug 12 02:36:24 2005 @@ -5,6 +5,7 @@ from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo from pypy.translator.c.funcgen import FunctionCodeGenerator from pypy.translator.c.external import CExternalFunctionCodeGenerator +from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring from pypy.translator.c.support import cdecl, somelettersfrom from pypy.translator.c.primitive import PrimitiveType from pypy.translator.c import extfunc @@ -280,10 +281,16 @@ # ____________________________________________________________ -class ContainerNode: - includes = () +class ContainerNode(object): + if USESLOTS: + __slots__ = """db T obj + typename implementationtypename + name ptrname + globalcontainer + includes""".split() def __init__(self, db, T, obj): + self.includes = () self.db = db self.T = T self.obj = obj @@ -319,8 +326,11 @@ def getlength(self): return 1 +assert not USESLOTS or '__dict__' not in dir(ContainerNode) class StructNode(ContainerNode): + if USESLOTS: + __slots__ = () def basename(self): return self.T._name @@ -350,8 +360,11 @@ yield '\t%s' % expr yield '}' +assert not USESLOTS or '__dict__' not in dir(StructNode) class ArrayNode(ContainerNode): + if USESLOTS: + __slots__ = () def basename(self): return 'array' @@ -379,6 +392,7 @@ yield '\t%s' % expr yield '} }' +assert not USESLOTS or '__dict__' not in dir(ArrayNode) def generic_initializationexpr(db, value, access_expr, decoration): if isinstance(typeOf(value), ContainerType): @@ -406,9 +420,11 @@ class FuncNode(ContainerNode): - globalcontainer = True + if USESLOTS: + __slots__ = """funcgen""".split() def __init__(self, db, T, obj): + self.globalcontainer = True self.funcgen = select_function_code_generator(obj, db) self.db = db self.T = T @@ -422,6 +438,7 @@ self.includes = obj.includes self.name = self.basename() else: + self.includes = () self.name = db.namespace.uniquename('g_' + self.basename()) self.ptrname = self.name @@ -443,6 +460,7 @@ funcgen = self.funcgen if funcgen is None: return + funcgen.implementation_begin() yield '%s {' % cdecl(self.implementationtypename, self.name) # # declare the local variables @@ -483,7 +501,9 @@ if lineprefix: # unlikely yield lineprefix yield '}' + funcgen.implementation_end() +assert not USESLOTS or '__dict__' not in dir(FuncNode) def select_function_code_generator(fnobj, db): if fnobj._callable in extfunc.EXTERNALS: @@ -511,6 +531,7 @@ class OpaqueNode(ContainerNode): globalcontainer = True typename = 'void (@)(void *)' + includes = () def __init__(self, db, T, obj): assert T == RuntimeTypeInfo @@ -535,6 +556,7 @@ globalcontainer = True typename = 'PyObject @' implementationtypename = 'PyObject *@' + includes = () def __init__(self, db, T, obj): # obj is a _pyobject here; obj.value is the underlying CPython object Modified: pypy/dist/pypy/translator/c/support.py ============================================================================== --- pypy/dist/pypy/translator/c/support.py (original) +++ pypy/dist/pypy/translator/c/support.py Fri Aug 12 02:36:24 2005 @@ -1,6 +1,13 @@ from pypy.rpython import lltype from pypy.translator.gensupp import NameManager +# +# use __slots__ declarations for node classes etc +# possible to turn it off while refactoring, experimenting +# +USESLOTS = True + + class ErrorValue: def __init__(self, TYPE): self.TYPE = TYPE From adim at codespeak.net Fri Aug 12 09:37:56 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Fri, 12 Aug 2005 09:37:56 +0200 (CEST) Subject: [pypy-svn] r15995 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050812073756.5C24B27B64@code1.codespeak.net> Author: adim Date: Fri Aug 12 09:37:54 2005 New Revision: 15995 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py Log: minor cleaning/renaming Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Fri Aug 12 09:37:54 2005 @@ -5,7 +5,6 @@ from grammar import BaseGrammarBuilder, AbstractContext from pypy.interpreter.astcompiler import ast, consts -from pypy.interpreter.astcompiler.transformer import WalkerError import pypy.interpreter.pyparser.pysymbol as sym import pypy.interpreter.pyparser.pytoken as tok @@ -261,30 +260,30 @@ return doc -def to_lvalue(ast_node, OP): +def to_lvalue(ast_node, flags): if isinstance( ast_node, ast.Name ): - return ast.AssName( ast_node.name, OP ) + return ast.AssName( ast_node.name, flags ) elif isinstance(ast_node, ast.Tuple): nodes = [] for node in ast_node.getChildren(): - nodes.append(to_lvalue(node, OP)) + nodes.append(to_lvalue(node, flags)) # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssTuple(nodes) elif isinstance(ast_node, ast.List): nodes = [] for node in ast_node.getChildren(): - nodes.append(to_lvalue(node, OP)) + nodes.append(to_lvalue(node, flags)) # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssList(nodes) elif isinstance(ast_node, ast.Getattr): expr = ast_node.expr attrname = ast_node.attrname - return ast.AssAttr(expr, attrname, OP) + return ast.AssAttr(expr, attrname, flags) elif isinstance(ast_node, ast.Subscript): - ast_node.flags = OP + ast_node.flags = flags return ast_node elif isinstance(ast_node, ast.Slice): - ast_node.flags = OP + ast_node.flags = flags return ast_node else: assert False, "TODO" @@ -298,17 +297,17 @@ return False def get_atoms( builder, nb ): - L = [] + atoms = [] i = nb while i>0: obj = builder.pop() if isinstance(obj, RuleObject): i += obj.count else: - L.append( obj ) + atoms.append( obj ) i -= 1 - L.reverse() - return L + atoms.reverse() + return atoms def eval_number(value): """temporary implementation""" @@ -400,19 +399,19 @@ ## def build_atom(builder, nb): - L = get_atoms( builder, nb ) - top = L[0] + atoms = get_atoms( builder, nb ) + top = atoms[0] if isinstance(top, TokenObject): if top.name == tok.LPAR: - if len(L) == 2: + if len(atoms) == 2: builder.push(ast.Tuple([], top.line)) else: - builder.push( L[1] ) + builder.push( atoms[1] ) elif top.name == tok.LSQB: - if len(L) == 2: + if len(atoms) == 2: builder.push(ast.List([], top.line)) else: - list_node = L[1] + list_node = atoms[1] # XXX lineno is not on *every* child class of ast.Node # (will probably crash the annotator, but should be # easily fixed) @@ -420,60 +419,60 @@ builder.push(list_node) elif top.name == tok.LBRACE: items = [] - for index in range(1, len(L)-1, 4): + for index in range(1, len(atoms)-1, 4): # a : b , c : d # ^ +1 +2 +3 +4 - items.append((L[index], L[index+2])) + items.append((atoms[index], atoms[index+2])) builder.push(ast.Dict(items, top.line)) elif top.name == tok.NAME: builder.push( ast.Name(top.value) ) elif top.name == tok.NUMBER: builder.push( ast.Const(eval_number(top.value)) ) elif top.name == tok.STRING: - # need to concatenate strings in L + # need to concatenate strings in atoms s = '' - for token in L: + for token in atoms: s += eval_string(token.value) builder.push( ast.Const(s) ) # assert False, "TODO (String)" elif top.name == tok.BACKQUOTE: - builder.push(ast.Backquote(L[1])) + builder.push(ast.Backquote(atoms[1])) else: - raise ValueError, "unexpected tokens (%d): %s" % (nb, [str(i) for i in L]) + raise ValueError, "unexpected tokens (%d): %s" % (nb, [str(i) for i in atoms]) def build_power(builder, nb): """power: atom trailer* ['**' factor]""" - L = get_atoms(builder, nb) - if len(L) == 1: - builder.push(L[0]) + atoms = get_atoms(builder, nb) + if len(atoms) == 1: + builder.push(atoms[0]) else: - if isinstance(L[-2], TokenObject) and L[-2].name == tok.DOUBLESTAR: - obj = parse_attraccess(L[:-2]) - builder.push(ast.Power([obj, L[-1]])) + if isinstance(atoms[-2], TokenObject) and atoms[-2].name == tok.DOUBLESTAR: + obj = parse_attraccess(atoms[:-2]) + builder.push(ast.Power([obj, atoms[-1]])) else: - obj = parse_attraccess(L) + obj = parse_attraccess(atoms) builder.push(obj) def build_factor( builder, nb ): - L = get_atoms( builder, nb ) - if len(L) == 1: - builder.push( L[0] ) - elif len(L) == 2 and isinstance(L[0],TokenObject): - if L[0].name == tok.PLUS: - builder.push( ast.UnaryAdd( L[1] ) ) - if L[0].name == tok.MINUS: - builder.push( ast.UnarySub( L[1] ) ) - if L[0].name == tok.TILDE: - builder.push( ast.Invert( L[1] ) ) + atoms = get_atoms( builder, nb ) + if len(atoms) == 1: + builder.push( atoms[0] ) + elif len(atoms) == 2 and isinstance(atoms[0],TokenObject): + if atoms[0].name == tok.PLUS: + builder.push( ast.UnaryAdd( atoms[1] ) ) + if atoms[0].name == tok.MINUS: + builder.push( ast.UnarySub( atoms[1] ) ) + if atoms[0].name == tok.TILDE: + builder.push( ast.Invert( atoms[1] ) ) def build_term( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) - left = L[0] + atoms = get_atoms( builder, nb ) + l = len(atoms) + left = atoms[0] for i in range(2,l,2): - right = L[i] - op = L[i-1].name + right = atoms[i] + op = atoms[i-1].name if op == tok.STAR: left = ast.Mul( [ left, right ] ) elif op == tok.SLASH: @@ -483,49 +482,49 @@ elif op == tok.DOUBLESLASH: left = ast.FloorDiv( [ left, right ] ) else: - raise ValueError, "unexpected token: %s" % L[i-1] + raise ValueError, "unexpected token: %s" % atoms[i-1] builder.push( left ) def build_arith_expr( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) - left = L[0] + atoms = get_atoms( builder, nb ) + l = len(atoms) + left = atoms[0] for i in range(2,l,2): - right = L[i] - op = L[i-1].name + right = atoms[i] + op = atoms[i-1].name if op == tok.PLUS: left = ast.Add( [ left, right ] ) elif op == tok.MINUS: left = ast.Sub( [ left, right ] ) else: - raise ValueError, "unexpected token: %s : %s" % L[i-1] + raise ValueError, "unexpected token: %s : %s" % atoms[i-1] builder.push( left ) def build_shift_expr( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) - left = L[0] + atoms = get_atoms( builder, nb ) + l = len(atoms) + left = atoms[0] for i in range(2,l,2): - right = L[i] - op = L[i-1].name + right = atoms[i] + op = atoms[i-1].name if op == tok.LEFTSHIFT: left = ast.LeftShift( [ left, right ] ) elif op == tok.RIGHTSHIFT: left = ast.RightShift( [ left, right ] ) else: - raise ValueError, "unexpected token: %s : %s" % L[i-1] + raise ValueError, "unexpected token: %s : %s" % atoms[i-1] builder.push( left ) def build_binary_expr(builder, nb, OP): - L = get_atoms(builder, nb) - l = len(L) + atoms = get_atoms(builder, nb) + l = len(atoms) if l==1: - builder.push( L[0] ) + builder.push( atoms[0] ) return items = [] - for i in range(0,l,2): # this is L not 1 - items.append( L[i] ) + for i in range(0,l,2): # this is atoms not 1 + items.append( atoms[i] ) builder.push( OP( items ) ) return @@ -539,22 +538,22 @@ return build_binary_expr( builder, nb, ast.Bitor ) def build_comparison( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) + atoms = get_atoms( builder, nb ) + l = len(atoms) if l == 1: - builder.push( L[0] ) + builder.push( atoms[0] ) return else: # a < b < c is transalted into: # Compare(Name('a'), [('<', Name(b)), ('<', Name(c))]) - left_token = L[0] + left_token = atoms[0] ops = [] for i in range(1, l, 2): # if tok.name isn't in rpunct, then it should be # 'is', 'is not', 'not' or 'not in' => tok.value - op_name = tok.tok_rpunct.get(L[i].name, L[i].value) - ops.append((op_name, L[i+1])) - builder.push(ast.Compare(L[0], ops)) + op_name = tok.tok_rpunct.get(atoms[i].name, atoms[i].value) + ops.append((op_name, atoms[i+1])) + builder.push(ast.Compare(atoms[0], ops)) def build_comp_op(builder, nb): """comp_op reducing has 2 different cases: @@ -569,14 +568,14 @@ operator is one and only one token on the stack (which is not the case, by default, with 'not in' and 'is not') """ - L = get_atoms(builder, nb) - l = len(L) + atoms = get_atoms(builder, nb) + l = len(atoms) # l==1 means '<', '>', '<=', etc. if l == 1: - builder.push(L[0]) + builder.push(atoms[0]) # l==2 means 'not in' or 'is not' elif l == 2: - if L[0].value == 'not': + if atoms[0].value == 'not': builder.push(TokenObject(tok.NAME, 'not in', None)) else: builder.push(TokenObject(tok.NAME, 'is not', None)) @@ -587,13 +586,13 @@ return build_binary_expr( builder, nb, ast.And ) def build_not_test(builder, nb): - L = get_atoms(builder, nb) - if len(L) == 1: - builder.push(L[0]) - elif len(L) == 2: - builder.push(ast.Not(L[1])) + atoms = get_atoms(builder, nb) + if len(atoms) == 1: + builder.push(atoms[0]) + elif len(atoms) == 2: + builder.push(ast.Not(atoms[1])) else: - assert False, "not_test implementation incomplete (%s)" % L + assert False, "not_test implementation incomplete (%s)" % atoms def build_test( builder, nb ): return build_binary_expr(builder, nb, ast.Or) @@ -602,40 +601,39 @@ return build_binary_expr( builder, nb, ast.Tuple ) def build_expr_stmt( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) + atoms = get_atoms( builder, nb ) + l = len(atoms) if l==1: - builder.push( ast.Discard( L[0] ) ) + builder.push( ast.Discard( atoms[0] ) ) return - op = L[1] + op = atoms[1] if op.name == tok.EQUAL: nodes = [] for i in range(0,l-2,2): - lvalue = to_lvalue( L[i], consts.OP_ASSIGN ) + lvalue = to_lvalue( atoms[i], consts.OP_ASSIGN ) nodes.append( lvalue ) - rvalue = L[-1] + rvalue = atoms[-1] builder.push( ast.Assign( nodes, rvalue ) ) pass else: assert l==3 - lvalue = L[0] + lvalue = atoms[0] assert is_augassign( lvalue ) - builder.push( ast.AugAssign( lvalue, op.get_name(), L[2] ) ) + builder.push( ast.AugAssign( lvalue, op.get_name(), atoms[2] ) ) def return_one( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) - if l==1: - builder.push( L[0] ) - return - raise WalkerError("missing one node in stack") + atoms = get_atoms( builder, nb ) + l = len(atoms) + assert l == 1, "missing one node in stack" + builder.push( atoms[0] ) + return def build_simple_stmt( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) + atoms = get_atoms( builder, nb ) + l = len(atoms) nodes = [] for n in range(0,l,2): - node = L[n] + node = atoms[n] if isinstance(node, TokenObject) and node.name == tok.NEWLINE: nodes.append(ast.Discard(ast.Const(None))) else: @@ -643,20 +641,20 @@ builder.push(ast.Stmt(nodes)) def build_return_stmt(builder, nb): - L = get_atoms(builder, nb) - if len(L) > 2: + atoms = get_atoms(builder, nb) + if len(atoms) > 2: assert False, "return several stmts not implemented" - elif len(L) == 1: + elif len(atoms) == 1: builder.push(ast.Return(ast.Const(None), None)) # XXX lineno else: - builder.push(ast.Return(L[1], None)) # XXX lineno + builder.push(ast.Return(atoms[1], None)) # XXX lineno def build_file_input(builder, nb): # FIXME: need to handle docstring ! doc = None stmts = [] - L = get_atoms(builder, nb) - for node in L: + atoms = get_atoms(builder, nb) + for node in atoms: if isinstance(node, ast.Stmt): stmts.extend(node.nodes) elif isinstance(node, TokenObject) and node.name == tok.ENDMARKER: @@ -671,28 +669,28 @@ return builder.push(ast.Module(doc, main_stmt)) def build_single_input( builder, nb ): - L = get_atoms( builder, nb ) - l = len(L) + atoms = get_atoms( builder, nb ) + l = len(atoms) if l >= 1: - builder.push(ast.Module(None, L[0])) + builder.push(ast.Module(None, atoms[0])) else: assert False, "Forbidden path" def build_testlist_gexp(builder, nb): - L = get_atoms(builder, nb) - l = len(L) + atoms = get_atoms(builder, nb) + l = len(atoms) if l == 1: - builder.push(L[0]) + builder.push(atoms[0]) return items = [] - if L[1].name == tok.COMMA: - for i in range(0, l, 2): # this is L not 1 - items.append(L[i]) + if atoms[1].name == tok.COMMA: + for i in range(0, l, 2): # this is atoms not 1 + items.append(atoms[i]) else: # genfor: 'i for i in j' # GenExpr(GenExprInner(Name('i'), [GenExprFor(AssName('i', 'OP_ASSIGN'), Name('j'), [])])))])) - expr = L[0] - genexpr_for = parse_genexpr_for(L[1:]) + expr = atoms[0] + genexpr_for = parse_genexpr_for(atoms[1:]) builder.push(ast.GenExpr(ast.GenExprInner(expr, genexpr_for))) return builder.push(ast.Tuple(items)) @@ -702,64 +700,64 @@ pass def build_lambdef(builder, nb): - L = get_atoms(builder, nb) - code = L[-1] - names, defaults, flags = parse_arglist(L[1:-2]) + atoms = get_atoms(builder, nb) + code = atoms[-1] + names, defaults, flags = parse_arglist(atoms[1:-2]) builder.push(ast.Lambda(names, defaults, flags, code)) def build_trailer(builder, nb): """trailer: '(' ')' | '(' arglist ')' | '[' subscriptlist ']' | '.' NAME """ - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) # Case 1 : '(' ... - if L[0].name == tok.LPAR: - if len(L) == 2: # and L[1].token == tok.RPAR: + if atoms[0].name == tok.LPAR: + if len(atoms) == 2: # and atoms[1].token == tok.RPAR: builder.push(ArglistObject('arglist', ([], None, None), None)) - elif len(L) == 3: # '(' Arglist ')' + elif len(atoms) == 3: # '(' Arglist ')' # push arglist on the stack - builder.push(L[1]) - elif L[0].name == tok.LSQB: - if isinstance(L[1], SlicelistObject): - builder.push(L[1]) + builder.push(atoms[1]) + elif atoms[0].name == tok.LSQB: + if isinstance(atoms[1], SlicelistObject): + builder.push(atoms[1]) else: subs = [] - for index in range(1, len(L), 2): - subs.append(L[index]) + for index in range(1, len(atoms), 2): + subs.append(atoms[index]) builder.push(SubscriptObject('subscript', subs, None)) - elif len(L) == 2: + elif len(atoms) == 2: # Attribute access: '.' NAME # XXX Warning: fails if trailer is used in lvalue - builder.push(L[0]) - builder.push(L[1]) + builder.push(atoms[0]) + builder.push(atoms[1]) builder.push(TempRuleObject('pending-attr-access', 2, None)) else: assert False, "Trailer reducing implementation incomplete !" def build_arglist(builder, nb): - L = get_atoms(builder, nb) - builder.push(ArglistObject('arglist', parse_argument(L), None)) + atoms = get_atoms(builder, nb) + builder.push(ArglistObject('arglist', parse_argument(atoms), None)) def build_subscript(builder, nb): """'.' '.' '.' | [test] ':' [test] [':' [test]] | test""" - L = get_atoms(builder, nb) - if isinstance(L[0], TokenObject) and L[0].name == tok.DOT: + atoms = get_atoms(builder, nb) + if isinstance(atoms[0], TokenObject) and atoms[0].name == tok.DOT: # Ellipsis: builder.push(ast.Ellipsis()) - elif len(L) == 1: - token = L[0] + elif len(atoms) == 1: + token = atoms[0] if isinstance(token, TokenObject) and token.name == tok.COLON: sliceinfos = [None, None, None] builder.push(SlicelistObject('slice', sliceinfos, None)) else: # test - builder.push(L[0]) - else: # elif len(L) > 1: + builder.push(atoms[0]) + else: # elif len(atoms) > 1: items = [] sliceinfos = [None, None, None] infosindex = 0 subscript_type = 'subscript' - for token in L: + for token in atoms: if isinstance(token, TokenObject): if token.name == tok.COLON: infosindex += 1 @@ -789,29 +787,29 @@ def build_listmaker(builder, nb): """listmaker: test ( list_for | (',' test)* [','] )""" - L = get_atoms(builder, nb) - if len(L) >= 2 and isinstance(L[1], TokenObject) and L[1].value == 'for': + atoms = get_atoms(builder, nb) + if len(atoms) >= 2 and isinstance(atoms[1], TokenObject) and atoms[1].value == 'for': # list comp - expr = L[0] - list_for = parse_listcomp(L[1:]) + expr = atoms[0] + list_for = parse_listcomp(atoms[1:]) builder.push(ast.ListComp(expr, list_for)) else: # regular list building (like in [1, 2, 3,]) index = 0 nodes = [] - while index < len(L): - nodes.append(L[index]) + while index < len(atoms): + nodes.append(atoms[index]) index += 2 # skip comas builder.push(ast.List(nodes)) def build_decorator(builder, nb): """decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE""" - L = get_atoms(builder, nb) - print "***** decorator", L + atoms = get_atoms(builder, nb) + print "***** decorator", atoms nodes = [] - # remove '@', '(' and ')' from L and use parse_attraccess - for token in L[1:]: + # remove '@', '(' and ')' from atoms and use parse_attraccess + for token in atoms[1:]: if isinstance(token, TokenObject) and \ token.name in (tok.LPAR, tok.RPAR, tok.NEWLINE): # skip those ones @@ -824,28 +822,28 @@ def build_funcdef(builder, nb): """funcdef: [decorators] 'def' NAME parameters ':' suite """ - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) index = 0 decorators = [] decorator_node = None - while not (isinstance(L[index], TokenObject) and L[index].value == 'def'): - decorators.append(L[index]) + while not (isinstance(atoms[index], TokenObject) and atoms[index].value == 'def'): + decorators.append(atoms[index]) index += 1 if decorators: decorator_node = ast.Decorators(decorators) - L = L[index:] - funcname = L[1] + atoms = atoms[index:] + funcname = atoms[1] arglist = [] index = 3 - arglist = L[3:-3] - # while not (isinstance(L[index], TokenObject) and L[index].name == tok.COLON): - # arglist.append(L[index]) + arglist = atoms[3:-3] + # while not (isinstance(atoms[index], TokenObject) and atoms[index].name == tok.COLON): + # arglist.append(atoms[index]) # index += 1 # arglist.pop() # remove ':' names, default, flags = parse_arglist(arglist) - funcname = L[1].value - arglist = L[2] - code = L[-1] + funcname = atoms[1].value + arglist = atoms[2] + code = atoms[-1] doc = get_docstring(code) # FIXME: decorators and docstring ! builder.push(ast.Function(decorator_node, funcname, names, default, flags, doc, code)) @@ -853,17 +851,17 @@ def build_classdef(builder, nb): """classdef: 'class' NAME ['(' testlist ')'] ':' suite""" - L = get_atoms(builder, nb) - l = len(L) + atoms = get_atoms(builder, nb) + l = len(atoms) # FIXME: docstring - classname = L[1].value + classname = atoms[1].value if l == 4: basenames = [] - body = L[3] + body = atoms[3] elif l == 7: basenames = [] - body = L[6] - base = L[3] + body = atoms[6] + base = atoms[3] if isinstance(base, ast.Tuple): for node in base.nodes: basenames.append(node) @@ -874,19 +872,19 @@ def build_suite(builder, nb): """suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT""" - L = get_atoms(builder, nb) - if len(L) == 1: - builder.push(L[0]) - elif len(L) == 4: + atoms = get_atoms(builder, nb) + if len(atoms) == 1: + builder.push(atoms[0]) + elif len(atoms) == 4: # Only one statement for (stmt+) - stmt = L[2] + stmt = atoms[2] if not isinstance(stmt, ast.Stmt): stmt = ast.Stmt([stmt]) builder.push(stmt) else: # several statements stmts = [] - nodes = L[2:-1] + nodes = atoms[2:-1] for node in nodes: if isinstance(node, ast.Stmt): stmts.extend(node.nodes) @@ -896,83 +894,83 @@ def build_if_stmt(builder, nb): - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) tests = [] - tests.append((L[1], L[3])) + tests.append((atoms[1], atoms[3])) index = 4 else_ = None - while index < len(L): - cur_token = L[index] + while index < len(atoms): + cur_token = atoms[index] assert isinstance(cur_token, TokenObject) # rtyper if cur_token.value == 'elif': - tests.append((L[index+1], L[index+3])) + tests.append((atoms[index+1], atoms[index+3])) index += 4 else: # cur_token.value == 'else' - else_ = L[index+2] + else_ = atoms[index+2] break # break is not necessary builder.push(ast.If(tests, else_)) def build_pass_stmt(builder, nb): """past_stmt: 'pass'""" - L = get_atoms(builder, nb) - assert len(L) == 1 + atoms = get_atoms(builder, nb) + assert len(atoms) == 1 builder.push(ast.Pass()) def build_break_stmt(builder, nb): """past_stmt: 'pass'""" - L = get_atoms(builder, nb) - assert len(L) == 1 + atoms = get_atoms(builder, nb) + assert len(atoms) == 1 builder.push(ast.Break()) def build_for_stmt(builder, nb): """for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]""" - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) else_ = None # skip 'for' - assign = to_lvalue(L[1], consts.OP_ASSIGN) + assign = to_lvalue(atoms[1], consts.OP_ASSIGN) # skip 'in' - iterable = L[3] + iterable = atoms[3] # skip ':' - body = L[5] + body = atoms[5] # if there is a "else" statement - if len(L) > 6: + if len(atoms) > 6: # skip 'else' and ':' - else_ = L[8] + else_ = atoms[8] builder.push(ast.For(assign, iterable, body, else_)) def build_exprlist(builder, nb): - L = get_atoms(builder, nb) - if len(L) <= 2: - builder.push(L[0]) + atoms = get_atoms(builder, nb) + if len(atoms) <= 2: + builder.push(atoms[0]) else: names = [] - for index in range(0, len(L), 2): - names.append(L[index]) + for index in range(0, len(atoms), 2): + names.append(atoms[index]) builder.push(ast.Tuple(names)) def build_fplist(builder, nb): """fplist: fpdef (',' fpdef)* [',']""" - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) names = [] - for index in range(0, len(L), 2): - names.append(L[index].value) + for index in range(0, len(atoms), 2): + names.append(atoms[index].value) builder.push(FPListObject('fplist', tuple(names), None)) def build_while_stmt(builder, nb): """while_stmt: 'while' test ':' suite ['else' ':' suite]""" - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) else_ = None # skip 'while' - test = L[1] + test = atoms[1] # skip ':' - body = L[3] + body = atoms[3] # if there is a "else" statement - if len(L) > 4: + if len(atoms) > 4: # skip 'else' and ':' - else_ = L[6] + else_ = atoms[6] builder.push(ast.While(test, body, else_)) @@ -988,22 +986,22 @@ XXX: refactor build_import_name and build_import_from """ - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) index = 1 # skip 'import' - l = len(L) + l = len(atoms) names = [] while index < l: as_name = None # dotted name (a.b.c) - incr, name = parse_dotted_names(L[index:]) + incr, name = parse_dotted_names(atoms[index:]) index += incr # 'as' value - if index < l and L[index].value == 'as': - as_name = L[index+1].value + if index < l and atoms[index].value == 'as': + as_name = atoms[index+1].value index += 2 names.append((name, as_name)) # move forward until next ',' - while index < l and L[index].name != tok.COMMA: + while index < l and atoms[index].name != tok.COMMA: index += 1 index += 1 builder.push(ast.Import(names)) @@ -1016,18 +1014,18 @@ import_as_names: import_as_name (',' import_as_name)* [','] import_as_name: NAME [NAME NAME] """ - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) index = 1 - incr, from_name = parse_dotted_names(L[index:]) + incr, from_name = parse_dotted_names(atoms[index:]) index += (incr + 1) # skip 'import' - if L[index].name == tok.STAR: + if atoms[index].name == tok.STAR: names = [('*', None)] else: - if L[index].name == tok.LPAR: + if atoms[index].name == tok.LPAR: # mutli-line imports - tokens = L[index+1:-1] + tokens = atoms[index+1:-1] else: - tokens = L[index:] + tokens = atoms[index:] index = 0 l = len(tokens) names = [] @@ -1046,67 +1044,67 @@ def build_yield_stmt(builder, nb): - L = get_atoms(builder, nb) - builder.push(ast.Yield(L[1])) + atoms = get_atoms(builder, nb) + builder.push(ast.Yield(atoms[1])) def build_continue_stmt(builder, nb): - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) builder.push(ast.Continue()) def build_del_stmt(builder, nb): - L = get_atoms(builder, nb) - builder.push(to_lvalue(L[1], consts.OP_DELETE)) + atoms = get_atoms(builder, nb) + builder.push(to_lvalue(atoms[1], consts.OP_DELETE)) def build_assert_stmt(builder, nb): """assert_stmt: 'assert' test [',' test]""" - L = get_atoms(builder, nb) - test = L[1] - if len(L) == 4: - fail = L[3] + atoms = get_atoms(builder, nb) + test = atoms[1] + if len(atoms) == 4: + fail = atoms[3] else: fail = None builder.push(ast.Assert(test, fail)) def build_exec_stmt(builder, nb): """exec_stmt: 'exec' expr ['in' test [',' test]]""" - L = get_atoms(builder, nb) - expr = L[1] + atoms = get_atoms(builder, nb) + expr = atoms[1] loc = None glob = None - if len(L) > 2: - loc = L[3] - if len(L) > 4: - glob = L[5] + if len(atoms) > 2: + loc = atoms[3] + if len(atoms) > 4: + glob = atoms[5] builder.push(ast.Exec(expr, loc, glob)) def build_print_stmt(builder, nb): """ print_stmt: 'print' ( '>>' test [ (',' test)+ [','] ] | [ test (',' test)* [','] ] ) """ - L = get_atoms(builder, nb) - l = len(L) + atoms = get_atoms(builder, nb) + l = len(atoms) items = [] dest = None start = 1 if l > 1: - if isinstance(L[1], TokenObject) and L[1].name == tok.RIGHTSHIFT: - dest = L[2] + if isinstance(atoms[1], TokenObject) and atoms[1].name == tok.RIGHTSHIFT: + dest = atoms[2] # skip following comma start = 4 for index in range(start, l, 2): - items.append(L[index]) - if isinstance(L[-1], TokenObject) and L[-1].name == tok.COMMA: + items.append(atoms[index]) + if isinstance(atoms[-1], TokenObject) and atoms[-1].name == tok.COMMA: builder.push(ast.Print(items, dest)) else: builder.push(ast.Printnl(items, dest)) def build_global_stmt(builder, nb): """global_stmt: 'global' NAME (',' NAME)*""" - L = get_atoms(builder, nb) + atoms = get_atoms(builder, nb) names = [] - for index in range(1, len(L), 2): - token = L[index] + for index in range(1, len(atoms), 2): + token = atoms[index] assert isinstance(token, TokenObject) names.append(token.value) builder.push(ast.Global(names)) @@ -1114,17 +1112,17 @@ def build_raise_stmt(builder, nb): """raise_stmt: 'raise' [test [',' test [',' test]]]""" - L = get_atoms(builder, nb) - l = len(L) + atoms = get_atoms(builder, nb) + l = len(atoms) expr1 = None expr2 = None expr3 = None if l >= 2: - expr1 = L[1] + expr1 = atoms[1] if l >= 4: - expr2 = L[3] + expr2 = atoms[3] if l == 6: - expr3 = L[5] + expr3 = atoms[5] builder.push(ast.Raise(expr1, expr2, expr3)) def build_try_stmt(builder, nb): @@ -1135,26 +1133,26 @@ except_clause: 'except' [test [',' test]] """ - L = get_atoms(builder, nb) - l = len(L) + atoms = get_atoms(builder, nb) + l = len(atoms) handlers = [] else_ = None - body = L[2] - token = L[3] + body = atoms[2] + token = atoms[3] assert isinstance(token, TokenObject) if token.value == 'finally': - builder.push(ast.TryFinally(body, L[5])) + builder.push(ast.TryFinally(body, atoms[5])) else: # token.value == 'except' index = 3 - while index < l and L[index].value == 'except': - tokens_read, expr1, expr2, except_body = parse_except_clause(L[index:]) + while index < l and atoms[index].value == 'except': + tokens_read, expr1, expr2, except_body = parse_except_clause(atoms[index:]) handlers.append((expr1, expr2, except_body)) index += tokens_read if index < l: - token = L[index] + token = atoms[index] assert isinstance(token, TokenObject) assert token.value == 'else' - else_ = L[index+2] # skip ':' + else_ = atoms[index+2] # skip ':' builder.push(ast.TryExcept(body, handlers, else_)) @@ -1247,7 +1245,8 @@ self.col = 0 # src.getcol() def get_name(self): - return tok.tok_rpunct.get(self.name, tok.tok_name.get(self.name,str(self.name))) + return tok.tok_rpunct.get(self.name, + tok.tok_name.get(self.name, str(self.name))) def __str__(self): return "" % (self.get_name(), self.value) @@ -1368,17 +1367,16 @@ if rule.is_root(): if DEBUG_MODE: print "ALT:", sym.sym_name[rule.codename], self.rule_stack - F = ASTRULES.get(rule.codename) - if F: - # print "REDUCING ALTERNATIVE %s" % sym.sym_name[rule.codename] - F( self, 1 ) + builder_func = ASTRULES.get(rule.codename, None) + if builder_func: + builder_func(self, 1) else: if DEBUG_MODE: print "No reducing implementation for %s, just push it on stack" % ( sym.sym_name[rule.codename]) - self.push_rule( rule.codename, 1, source ) + self.push_rule(rule.codename, 1, source) else: - self.push_rule( rule.codename, 1, source ) + self.push_rule(rule.codename, 1, source) if DEBUG_MODE > 1: show_stack(rule_stack, self.rule_stack) x = raw_input("Continue ?") @@ -1390,38 +1388,38 @@ if rule.is_root(): if DEBUG_MODE: print "SEQ:", sym.sym_name[rule.codename] - F = ASTRULES.get(rule.codename) - if F: + builder_func = ASTRULES.get(rule.codename) + if builder_func: # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename] - F( self, elts_number ) + builder_func(self, elts_number) else: if DEBUG_MODE: print "No reducing implementation for %s, just push it on stack" % ( sym.sym_name[rule.codename]) - self.push_rule( rule.codename, elts_number, source ) + self.push_rule(rule.codename, elts_number, source) else: - self.push_rule( rule.codename, elts_number, source ) + self.push_rule(rule.codename, elts_number, source) if DEBUG_MODE > 1: show_stack(rule_stack, self.rule_stack) - x = raw_input("Continue ?") + raw_input("Continue ?") return True def token(self, name, value, source): if DEBUG_MODE: print "TOK:", tok.tok_name[name], name, value - self.push_tok( name, value, source ) + self.push_tok(name, value, source) return True def show_stack(before, after): """debuggin helper function""" - L1 = len(before) - L2 = len(after) - for i in range(max(L1,L2)): - if i Author: hpk Date: Fri Aug 12 10:00:00 2005 New Revision: 15997 Added: pypy/extradoc/minute/pypy-sync-08-11-2005.txt Log: minutes of the pypy-sync meeting yesterday please correct/extend, if necessary, as soon as possible. i am going to send a note to pypy-dev later on. Added: pypy/extradoc/minute/pypy-sync-08-11-2005.txt ============================================================================== --- (empty file) +++ pypy/extradoc/minute/pypy-sync-08-11-2005.txt Fri Aug 12 10:00:00 2005 @@ -0,0 +1,362 @@ +============================================= +pypy-sync developer meeting 4th August 2005 +============================================= + +Attendees:: + + Samuele Pedroni, + Adrien Di Mascio, + Ludovic Aubrien, + Carl Friedrich Bolz, + Niklaus Heidimann, + Eric van Riet Paap, + Holger Krekel (minutes/moderation) + later: Richard Emslie, Michael Hudson, + Armin Rigo, Christian Tismer + +with pre info:: + Anders Lehmann + +Regular Topics +==================== + +- roll call. holger opens the meeting. + +- activity reports (3 prepared lines of info). + All Attendees submitted activity reports (see `IRC-Log`_ + at the end and 'LAST/NEXT/BLOCKERS' entries in particular) + +- resolve conflicts/blockers + No direct conflicts were discovered. Compliancy work was + discussed under its own topic. + +Topics of the week +=================== + +re / array status +------------------ + +Niklaus reports that _sre is feature-complete and passes +compliance tests. It's running mostly at application leve +and is thus quite slow. Niklaus is moving bits and pieces +to interpreter-level but it is not clear how the main +dispatching loop could be transformed this way (and especially +making it non-norecursive). Advice and comments welcome. +Niklaus will basically not be available until the Heidelberg sprint. + +Niklaus also reports that the array module is passing +the tests but lives fully at applevel. An open question +is how C data type sizes are modeled in PyPy. Samuele +notes that this depends on how we plan to interact +with user extensions. It is agreed that this particular +data-type size question is a post-0.7 issue. + + +llvm status +--------------------- + +Eric reports that the llvm is progressing steadily. There are +currently 10 exception raising operations left to implement. +Also some external (suggested_primitive) functions need to +be implemented as well as 64 bit support. The benchmarks +richards and bpnn can produce standalone executables +already! + +While working on the llvm backend, three bugs in the LLVM +tool chain itself were discovered, reported and fixed by +the LLVM guys very quickly. The current llvm file +can be found at http://codespeak.net/~ericvrp/download. +Eric thinks that a PyPy standalone version based on LLVM +is not far away! Everybody agrees that next week it would +make sense to plan an LLVM track (among other tracks) +for the Heidelberg sprint. + +GC and threading +--------------------------------- + +Two important aspects of the translated PyPy version +regard Garbage Collection and Threading. We planned +for having both GC and threading implemented as +translation aspects. While Carl is working on GC +(during his SoC project) we have no translation-aspect +code yet regarding threading integration. + +Carl reports that the pure simulator already works. +There is an Address class that provides raw access +to memory which should be used by the actual GC implementations. +This class is annotated with SomeAddress. On top of +this is the 'lltypesimulator', a class that behaves +like the _ptr type of pypy/rpython/lltype. Next +is implementing GC hooks into the llinterp and +then actually writing GC implementations. +An open issue is that the rtyper/specializer needs +to be extended to work with the new GC classes. + +Regarding threading there are various aspects +where discussion started: + +- support for "import thread" and the according API + at Python level could be regarded as a different + issue than providing new (stackless) threading techniques. + However, it's probably also possible (Armin thinks) + to offer this API on top of a stackless implementations. + +- threading support at the moment is (according to + Samuele) more about how we can weave translation + aspects into the translation machinery. Samuele + also emphasizes that supporting os-level threads means + quite some debugging work, also judging from Jython + experiences which offers free threading. + +more discussion is scheduled to happen at the technical +board meeting friday 12th August and probably best +more on pypy-dev itself (see Armin's `posting`_ and the +ensuing thread). + +.. _posting: http://codespeak.net/pipermail/pypy-dev/2005q3/002257.html + +FYI: codespeak migration status +----------------------------------- + +The migration of codespeak.net got postponed because the +target machine's network connectivity is not satisfying yet +(latency and dropped packets problems). However, commits +are now mirrored to the new machine which is basically +ready to take over in case the current machine gets problems. +It's possible that the services get migrated without +prior announcements (unless people really think it's +neccessary to pre announce that accordingly). + +This issue was postponed due to time restrictions +but it was mostly informational anyway. + +Closing +------------------ + +Holger closes the meeting in time at 13:30pm. + +.. _`IRC-log`: : + +Here is the full IRC log:: + + Aug 11 12:40:10 --> You are now talking on #pypy-sync + ... + Aug 11 13:00:51 ok, let's start? + Aug 11 13:01:01 yes + Aug 11 13:01:08 here is the agenda: + Aug 11 13:01:11 - roll call. + Aug 11 13:01:11 - activity reports (3 prepared lines of info). + Aug 11 13:01:11 - resolve conflicts/blockers + Aug 11 13:01:11 *Topics of the week* + Aug 11 13:01:11 - re / array status + Aug 11 13:01:11 - llvm status + Aug 11 13:01:11 - GC and threading + Aug 11 13:01:11 - codespeak migration status + Aug 11 13:01:27 i propose the following order for activity reports: + Aug 11 13:01:33 arigo, aleale, hpk, adim, cfbolz, ericvrp, nik, pedronis + Aug 11 13:01:44 --- You are now known as arigo + Aug 11 13:01:50 DONE: random small stuff; mostly done: proper exc handling in rtyper + Aug 11 13:01:50 NEXT: to be decided on the technical board meeting + Aug 11 13:01:50 BLOCKERS: - + Aug 11 13:01:56 hi + Aug 11 13:01:59 --- You are now known as aleale + Aug 11 13:02:05 PREV: Compliance tests + Aug 11 13:02:05 NEXT: Compliance tests + Aug 11 13:02:05 BLOCKERS: None + Aug 11 13:02:31 too many nick changes :-) + Aug 11 13:02:36 adim, can you continue? + Aug 11 13:02:40 LAST: astbuilder (starting to have good results) + Aug 11 13:02:40 NEXT: holidays + Aug 11 13:02:40 BLOCKERS: none + Aug 11 13:02:49 --- You are now known as hpk + Aug 11 13:03:00 LAST: codespeak.net migration, mentoring/user support + Aug 11 13:03:00 NEXT: some more codespeak-migration, open issues, at least three non-pypy days + Aug 11 13:03:00 BLOCKERS: None + Aug 11 13:03:16 PREV: none/helping adrien + Aug 11 13:03:17 NEXT: not much more + Aug 11 13:03:17 BLOCKERS: none + Aug 11 13:03:35 LAST: polished my lltype implementation on top of the memory simulation: it works quite well now (only 9 tests of all tests that use llinterp fail) + Aug 11 13:03:35 NEXT: implement a GC for the llinterp + Aug 11 13:03:35 BLOCKERS: None + Aug 11 13:03:45 last: progressing on full pypy translation with llvm + Aug 11 13:03:46 next: finishing external functions and exception raising operations + Aug 11 13:03:48 issues: possibly other llvm bugs + Aug 11 13:03:55 LAST: _sre and array tuning + Aug 11 13:04:00 NEXT: not much, will be at a conference in brussels from sunday until the sprint + Aug 11 13:04:04 BLOCKERS: none + Aug 11 13:04:22 Last: 2.4.1 tests, open issues, float ops/math and errors, a bit of tracker gardening, slottified lltype + Aug 11 13:04:24 Next: ll_math.h error handling, ? + Aug 11 13:04:25 Blockers: - + Aug 11 13:04:38 ok, thanks, there seems to be no blockers ... + Aug 11 13:04:50 except llvm bugs :-( + Aug 11 13:04:59 and except that some of the compliance work was a bit re-recommiting + Aug 11 13:05:08 but we can talk about this at the sprint or some other time i think + Aug 11 13:05:23 so on to the next topic: re / array status + Aug 11 13:05:29 --> rxe (n=rxe at client-82-14-80-179.manc.adsl.virgin.net) has joined #pypy-sync + Aug 11 13:05:33 hi + Aug 11 13:05:33 ok + Aug 11 13:05:41 _sre is feature-complete and fully compliant + Aug 11 13:05:47 rxe: we are in re/array status + Aug 11 13:05:49 only problem: it's very slow ;) + Aug 11 13:06:03 i'm slowly migrating some code to interp-level to improve that + Aug 11 13:06:11 but the core is running at applevel still? + Aug 11 13:06:16 yes + Aug 11 13:06:22 (i am not too accustomed to how re works internally) + Aug 11 13:06:36 the core dispatcher loop is at app-level + Aug 11 13:06:50 you basically have a plan how to put this to interp level? + Aug 11 13:07:00 no + Aug 11 13:07:03 it might be hard + Aug 11 13:07:09 to do it non-recursive + Aug 11 13:07:20 but not impossible + Aug 11 13:07:34 so would you need some helping advices from your mentors? + Aug 11 13:07:55 yes + Aug 11 13:08:06 i think this is best discussed at the sprint + Aug 11 13:08:12 --> mwh (N=user at 82-33-185-193.cable.ubr01.azte.blueyonder.co.uk) has joined #pypy-sync + Aug 11 13:08:14 as i will not have much time to work on it before that anyway + Aug 11 13:08:17 ok, especially since you will be away since then + Aug 11 13:08:18 right + Aug 11 13:08:24 then a few words about array? + Aug 11 13:08:42 mwh: hi, we are in the re/array topic already + Aug 11 13:08:42 array is also compliant + Aug 11 13:08:51 fully app-level at the moment + Aug 11 13:09:00 (i'm late and also only planning on lurking sorry) + Aug 11 13:09:00 there are conceptual issues: + Aug 11 13:09:18 do we respect a machine's C data type sizes? + Aug 11 13:09:24 ie the bytesize of a short int? + Aug 11 13:09:41 or is pypy like a vm with fixed data type sizes? + Aug 11 13:09:56 currently sizes are fixed, both in array and in struct + Aug 11 13:10:08 good question, pedronis, do you happen to have an opinion on that? + Aug 11 13:10:23 well, the fact is that those aspects are related to interaction with other ext (possibly user) modules + Aug 11 13:10:44 so until we have a model for that is hard to answer + Aug 11 13:10:46 yes. if a user dumps arrays to disk from CPython + Aug 11 13:10:54 and tries to read them with pypy's array + Aug 11 13:10:58 stuff can break at the moment + Aug 11 13:11:14 but it's a hard problem as array/struct assume a C backend + Aug 11 13:11:17 --> arigo (n=odie at bch-ma-195.epfl.ch) has joined #pypy-sync + Aug 11 13:11:18 i guess we should treat this question as a post-0.7 issue + Aug 11 13:11:27 yes + Aug 11 13:11:39 arigo: we are at the end of the re/array topic + Aug 11 13:11:53 ok, thanks Niklaus, then next topic: llvm status, eric? + Aug 11 13:12:03 (or rxe for that matter) + Aug 11 13:12:06 this is my prepared text: + Aug 11 13:12:07 The LLVM backend is progressing slowly but steadily. We currently have about 10 exception raising operations todo, + Aug 11 13:12:09 which is straightforward. The other open issue is the handful of external (suggested_primitive) functions that need + Aug 11 13:12:10 to be implemented. After a standalone version works, we need to refactor (of + Aug 11 13:12:12 course) and make the thing work on 64bit machines as well. + Aug 11 13:12:13 The benchmarks bpnn and Richards produce standalone executables already. (python llvm2/demo/richards l) + Aug 11 13:12:15 We encountered three bugs in the LLVM toolchain which after being reported to the LLVM team were all fixed very quickly. Which, in a way, gives me a good feeling. But discovering, reporting and waiting for fixes/workaround is what is costing us most of the time currently. I hope to have a working standalone mid next-week. + Aug 11 13:12:17 The current llvm file can be found at http://codespeak.net/~ericvrp/download + Aug 11 13:12:58 wow, i am impressed with the progress + Aug 11 13:13:07 me as well. very cool! + Aug 11 13:13:31 and you reported some 3 times being faster on richards/bpnn, right? + Aug 11 13:13:52 the only progress that counts (pypy) is still to come and I am not 100% sure if that will work first time round as did the C backend + Aug 11 13:14:07 well, the C backend didn't work exactly first time around :-) + Aug 11 13:14:17 about the speed: I don't know if the C backend does any gcc optimizations currently?!? + Aug 11 13:14:28 richard? + Aug 11 13:14:31 hpt: I think I reported the speed increase. + Aug 11 13:14:37 hpk + Aug 11 13:14:45 ericvrp: the 337 pystones where with -O2 i think + Aug 11 13:15:02 I have seen no llvm pystone benchmark results + Aug 11 13:15:09 and for richard/bpnn? + Aug 11 13:15:16 however i had modify bpnn to get speed increases + Aug 11 13:15:31 for/range to while loops + Aug 11 13:15:35 ah, ok, nevermind, that's not too important right now but interesting neverhteless + Aug 11 13:15:49 feel free to report any breakthroughts to pypy-dev, please + Aug 11 13:16:03 ok + Aug 11 13:16:08 :-) + Aug 11 13:16:09 i think it will make sense to have a "llvm" track at the heidelberg sprint + Aug 11 13:16:26 yes - I would like to see some unification of the backends + Aug 11 13:16:39 indeed, we should discuss this next week in some detail, i think + Aug 11 13:16:39 with the external functions and test esp + Aug 11 13:16:49 ok + Aug 11 13:16:56 yes - + Aug 11 13:17:18 ok, let's rush to the next topic: GC and threading + Aug 11 13:17:28 there is a mail from armin on pypy-dev + Aug 11 13:17:43 and carl, can you say a few words regarding GC and how it is supposed to integrate into PyPy? + Aug 11 13:17:56 I am not that far yet :-( + Aug 11 13:18:02 I did some groundwork, and hope that I can now actually start to work writing GCs + Aug 11 13:18:07 --> stakkars (i=mtsnwcw at i528C1380.versanet.de) has joined #pypy-sync + Aug 11 13:18:19 cfbolz: so you are at the pure simulator still + Aug 11 13:18:27 there is an Address class that provides raw access to memory and should be used by the GC implementation. this class is annotated with SomeAddress + Aug 11 13:18:35 hpk: yes + Aug 11 13:18:40 there is a memory simulator that simulates the address' behaviour + Aug 11 13:18:52 on top of this there is the lltypesimulator: a class that behaves like the _ptr type of lltype + Aug 11 13:19:17 the next thing I'm doing is imeplemting GC hooks into the llinterp for the + Aug 11 13:19:29 and then actually write a GC + Aug 11 13:19:37 there is still quite some stuff left: + Aug 11 13:19:56 the rtyper has to be extended to work with the GC stuff + Aug 11 13:20:13 plus some more unsolved problems + Aug 11 13:20:30 i see, but i guess you are in consultation with Samuele there + Aug 11 13:20:37 of course + Aug 11 13:21:14 ok, arigo, and all, i have a question regarding threading + Aug 11 13:21:14 one other problem: + Aug 11 13:21:21 no go on + Aug 11 13:21:40 doesn't it make sense to divide the discussion into "import thread" support and "new threading facilities"? + Aug 11 13:22:15 i mean we do need to offer the thread module, and e.g. stackless ideas or having multiple object spaes is a different issue, isn't it? + Aug 11 13:22:32 yes + Aug 11 13:23:24 arigo, pedronis: i am fine with raising and discussing this on pypy-dev, though, if further immediate comments cannot be made + Aug 11 13:23:34 well, you could hava import thread threads as user level threads + Aug 11 13:23:58 too bad that I missed the begining + Aug 11 13:24:11 pedronis: but that might already violate assumptions regarding compliancy? + Aug 11 13:24:34 stakkars: this is just the first discussion, more to follow and the pypy-dev thread is there as well + Aug 11 13:24:40 I don't think that threadidng is a compliancy problem + Aug 11 13:24:52 is more about showing what translating can achieve + Aug 11 13:24:58 at the moment + Aug 11 13:24:58 nor do I. It is an option which can be turned off + Aug 11 13:25:19 pedronis: i see the point but i am not sure i 100% agree + Aug 11 13:25:39 hpk: I think we can emulate the thread module with stackless translation + Aug 11 13:25:59 just by switching tasklets automatically every N bytecodes + Aug 11 13:26:21 maybe + Aug 11 13:26:25 well, supporting os threads means potentially quite some debugging + Aug 11 13:26:35 * hpk notes 4 minutes left + Aug 11 13:26:35 yes, I think so, too. I did some tests and theoretical musings. + Aug 11 13:26:37 threads are not nice that way + Aug 11 13:26:48 may I drop my 3 lines? + Aug 11 13:26:56 yes + Aug 11 13:27:01 cant we introduce OS threads and GIL except for IO? + Aug 11 13:27:02 Jython has free + Aug 11 13:27:23 DONE: integrated the new marshal module. Wrote exact string_to_float, moved it to interp-level, did some tests and theory about how to stackless + Aug 11 13:27:32 NEXT: write a book chapter on PyPy + Aug 11 13:27:39 BLOCK: time consumption due to memory fotprint and swapping, hard to track side effects of certain statements on the annotator + Aug 11 13:28:05 ok, let's continue gc+threading at pypy-dev and at the technical board meeting, last topic (3 minutes left) + Aug 11 13:28:10 Jython has free threading but is all quite delicate + Aug 11 13:28:19 the blocker is muc better since I pushed arigo/pedronis to slotify + Aug 11 13:28:40 codespeak.net migration is half-done + Aug 11 13:28:48 well, slottifying lltype killed 150m of memory usage + Aug 11 13:28:56 svn commits are mirrored to code2.codespeak.net seconds after the commit on the main hosts happens + Aug 11 13:29:01 yes, I noticed. + Aug 11 13:29:08 I don't know what happens combined with compacting node.py + Aug 11 13:29:20 * hpk stops with the topic + Aug 11 13:29:37 stakkars, pedronis: are you reading my comments? + Aug 11 13:29:48 where? + Aug 11 13:29:54 here + Aug 11 13:29:57 well, i tried to move to the next topic + Aug 11 13:30:04 but you conitnued with the old topic + Aug 11 13:30:04 which is it + Aug 11 13:30:13 pypy-sync has a very tight schedule + Aug 11 13:30:35 in fact, the meeting is closed now + Aug 11 13:30:54 it + Aug 11 13:31:09 pypy-sync is just for synchronisation not for full blown content discussions + Aug 11 13:31:13 * stakkars wonders why hpk wasted the rest instead of moving on + Aug 11 13:31:35 * pedronis to make his point + Aug 11 13:32:26 can i post 3 lines (sorry I was late)? + Aug 11 13:32:29 DONE: tiny llvm stuff + Aug 11 13:32:29 NEXT: llvm refactors / organise sprint travelling + Aug 11 13:32:29 BLOCKERS: new laptop + Aug 11 13:33:01 thanks, i'll add it to the minutes + Aug 11 13:33:16 bye + Aug 11 13:33:20 see you + Aug 11 13:33:21 bye + Aug 11 13:33:22 bye + Aug 11 13:33:24 bye + Aug 11 13:33:24 bye + Aug 11 13:33:25 bye + Aug 11 13:33:30 bye + Aug 11 13:33:35 <-- mwh (N=user at 82-33-185-193.cable.ubr01.azte.blueyonder.co.uk) has left #pypy-sync ("ERC Version 5.0 (CVS) $Revision: 1.767 $ (IRC client for Emacs)") + Aug 11 13:33:36 <-- stakkars (i=mtsnwcw at i528C1380.versanet.de) has left #pypy-sync + Aug 11 13:33:39 <-- adim (n=adim at logilab.net2.nerim.net) has left #pypy-sync + Aug 11 13:33:42 <-- nik (n=chatzill at 123.74.203.62.cust.bluewin.ch) has left #pypy-sync + Aug 11 13:33:43 <-- rxe (n=rxe at client-82-14-80-179.manc.adsl.virgin.net) has left #pypy-sync + Aug 11 13:33:49 <-- cfbolz (n=a at b0bar.physi.uni-heidelberg.de) has left #pypy-sync ("Leaving") + Aug 11 13:33:50 <-- ericvrp (N=chatzill at ericvrp.demon.nl) has left #pypy-sync + From hpk at codespeak.net Fri Aug 12 10:11:30 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 12 Aug 2005 10:11:30 +0200 (CEST) Subject: [pypy-svn] r15999 - pypy/extradoc/minute Message-ID: <20050812081130.A05A427B5E@code1.codespeak.net> Author: hpk Date: Fri Aug 12 10:11:29 2005 New Revision: 15999 Modified: pypy/extradoc/minute/pypy-sync-08-11-2005.txt Log: correct time info Modified: pypy/extradoc/minute/pypy-sync-08-11-2005.txt ============================================================================== --- pypy/extradoc/minute/pypy-sync-08-11-2005.txt (original) +++ pypy/extradoc/minute/pypy-sync-08-11-2005.txt Fri Aug 12 10:11:29 2005 @@ -1,7 +1,9 @@ ============================================= -pypy-sync developer meeting 4th August 2005 +pypy-sync developer meeting 11th August 2005 ============================================= +Time & location: 1pm (30 minutes) at #pypy-sync + Attendees:: Samuele Pedroni, From nik at codespeak.net Fri Aug 12 12:55:48 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 12 Aug 2005 12:55:48 +0200 (CEST) Subject: [pypy-svn] r16002 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050812105548.E8A9F27B64@code1.codespeak.net> Author: nik Date: Fri Aug 12 12:55:47 2005 New Revision: 16002 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_interp_sre.py Log: moved at dispatching to app-level. all is_X method are now only called from interp-level and return an interp-level boolean. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Fri Aug 12 12:55:47 2005 @@ -18,12 +18,6 @@ } interpleveldefs = { + '_at_dispatch': 'interp_sre.at_dispatch', '_category_dispatch': 'interp_sre.category_dispatch', - '_is_digit': 'interp_sre.is_digit', - '_is_space': 'interp_sre.is_space', - '_is_word': 'interp_sre.is_word', - '_is_uni_word': 'interp_sre.is_uni_word', - '_is_loc_word': 'interp_sre.is_loc_word', - '_is_linebreak': 'interp_sre.is_linebreak', - '_is_uni_linebreak': 'interp_sre.is_uni_linebreak', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 12 12:55:47 2005 @@ -494,21 +494,11 @@ def remaining_codes(self): return len(self.pattern_codes) - self.code_position - def at_beginning(self): - return self.string_position == 0 - def at_end(self): return self.string_position == self.state.end def at_linebreak(self): - return not self.at_end() and _sre._is_linebreak(self.peek_char()) - - def at_boundary(self, word_checker): - if self.at_beginning() and self.at_end(): - return False - that = not self.at_beginning() and word_checker(self.peek_char(-1)) - this = not self.at_end() and word_checker(self.peek_char()) - return this != that + return not self.at_end() and self.peek_char() == "\n" class _RepeatContext(_MatchContext): @@ -548,7 +538,6 @@ def __init__(self): self.executing_contexts = {} - self.at_dispatcher = _AtcodeDispatcher() self.set_dispatcher = _CharsetDispatcher() def match(self, context): @@ -632,7 +621,8 @@ # match at given position # #self._log(ctx, "AT", ctx.peek_code(1)) - if not self.at_dispatcher.dispatch(ctx.peek_code(1), ctx): + if not _sre._at_dispatch(ctx.peek_code(1), ctx.state.string, + ctx.string_position, ctx.state.end): ctx.has_matched = False return True ctx.skip_code(2) @@ -1149,37 +1139,6 @@ _CharsetDispatcher.build_dispatch_table(OPCODES, "set_") -class _AtcodeDispatcher(_Dispatcher): - - def at_beginning(self, ctx): - return ctx.at_beginning() - at_beginning_string = at_beginning - def at_beginning_line(self, ctx): - return ctx.at_beginning() or _sre._is_linebreak(ctx.peek_char(-1)) - def at_end(self, ctx): - return (ctx.remaining_chars() == 1 and ctx.at_linebreak()) or ctx.at_end() - def at_end_line(self, ctx): - return ctx.at_linebreak() or ctx.at_end() - def at_end_string(self, ctx): - return ctx.at_end() - def at_boundary(self, ctx): - return ctx.at_boundary(_sre._is_word) - def at_non_boundary(self, ctx): - return not ctx.at_boundary(_sre._is_word) - def at_loc_boundary(self, ctx): - return ctx.at_boundary(_sre._is_loc_word) - def at_loc_non_boundary(self, ctx): - return not ctx.at_boundary(_sre._is_loc_word) - def at_uni_boundary(self, ctx): - return ctx.at_boundary(_sre._is_uni_word) - def at_uni_non_boundary(self, ctx): - return not ctx.at_boundary(_sre._is_uni_word) - def unknown(self, ctx): - return False - -_AtcodeDispatcher.build_dispatch_table(ATCODES, "") - - def _log(message): if 0: print message Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 12 12:55:47 2005 @@ -20,44 +20,44 @@ def is_digit(space, w_char): code = space.int_w(space.ord(w_char)) - return space.newbool(code < 128 and ascii_char_info[code] & 1) + return code < 128 and ascii_char_info[code] & 1 def is_uni_digit(space, w_char): - return space.newbool(space.is_true(space.call_method(w_char, "isdigit"))) + return space.is_true(space.call_method(w_char, "isdigit")) def is_space(space, w_char): code = space.int_w(space.ord(w_char)) - return space.newbool(code < 128 and ascii_char_info[code] & 2) + return code < 128 and ascii_char_info[code] & 2 def is_uni_space(space, w_char): - return space.newbool(space.is_true(space.call_method(w_char, "isspace"))) + return space.is_true(space.call_method(w_char, "isspace")) def is_word(space, w_char): code = space.int_w(space.ord(w_char)) - return space.newbool(code < 128 and ascii_char_info[code] & 16) + return code < 128 and ascii_char_info[code] & 16 def is_uni_word(space, w_char): code = space.int_w(space.ord(w_char)) w_unichar = space.newunicode([code]) isalnum = space.is_true(space.call_method(w_unichar, "isalnum")) - return space.newbool(isalnum or code == underline) + return isalnum or code == underline def is_loc_word(space, w_char): code = space.int_w(space.ord(w_char)) if code > 255: - return space.newbool(False) + return False # Need to use this new w_char_not_uni from here on, because this one is # guaranteed to be not unicode. w_char_not_uni = space.wrap(chr(code)) isalnum = space.is_true(space.call_method(w_char_not_uni, "isalnum")) - return space.newbool(isalnum or code == underline) + return isalnum or code == underline def is_linebreak(space, w_char): - return space.newbool(space.int_w(space.ord(w_char)) == linebreak) + return space.int_w(space.ord(w_char)) == linebreak def is_uni_linebreak(space, w_char): code = space.int_w(space.ord(w_char)) - return space.newbool(uni_linebreaks.has_key(code)) + return uni_linebreaks.has_key(code) #### Category dispatch @@ -66,12 +66,12 @@ chcode = space.int_w(w_chcode) if chcode >= len(category_dispatch_table): return space.newbool(False) - w_function, negate = category_dispatch_table[chcode] - w_result = w_function(space, w_char) + function, negate = category_dispatch_table[chcode] + result = function(space, w_char) if negate: - return space.newbool(not space.is_true(w_result)) + return space.newbool(not result) else: - return w_result + return space.newbool(result) # Maps opcodes by indices to (function, negate) tuples. category_dispatch_table = [ @@ -83,3 +83,87 @@ (is_uni_word, True), (is_uni_linebreak, False), (is_uni_linebreak, True) ] + +##### At dispatch + +class MatchContext: + # XXX This is not complete. It's tailored to at dispatch currently. + + def __init__(self, space, w_string, string_position, end): + self.space = space + self.w_string = w_string + self.string_position = string_position + self.end = end + + def peek_char(self, peek=0): + return self.space.getitem(self.w_string, + self.space.wrap(self.string_position + peek)) + + def remaining_chars(self): + return self.end - self.string_position + + def at_beginning(self): + return self.string_position == 0 + + def at_end(self): + return self.string_position == self.end + + def at_linebreak(self): + return not self.at_end() and is_linebreak(self.space, self.peek_char()) + + def at_boundary(self, word_checker): + if self.at_beginning() and self.at_end(): + return False + that = not self.at_beginning() \ + and word_checker(self.space, self.peek_char(-1)) + this = not self.at_end() \ + and word_checker(self.space, self.peek_char()) + return this != that + +def at_dispatch(space, w_atcode, w_string, w_string_position, w_end): + # XXX temporary ugly method signature until we can call this from + # interp-level only + atcode = space.int_w(w_atcode) + if atcode >= len(at_dispatch_table): + return space.newbool(False) + context = MatchContext(space, w_string, space.int_w(w_string_position), + space.int_w(w_end)) + function, negate = at_dispatch_table[atcode] + result = function(space, context) + if negate: + return space.newbool(not result) + else: + return space.newbool(result) + +def at_beginning(space, ctx): + return ctx.at_beginning() + +def at_beginning_line(space, ctx): + return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(-1)) + +def at_end(space, ctx): + return ctx.at_end() or (ctx.remaining_chars() == 1 and ctx.at_linebreak()) + +def at_end_line(self, ctx): + return ctx.at_linebreak() or ctx.at_end() + +def at_end_string(self, ctx): + return ctx.at_end() + +def at_boundary(self, ctx): + return ctx.at_boundary(is_word) + +def at_loc_boundary(self, ctx): + return ctx.at_boundary(is_loc_word) + +def at_uni_boundary(self, ctx): + return ctx.at_boundary(is_uni_word) + +# Maps opcodes by indices to (function, negate) tuples. +at_dispatch_table = [ + (at_beginning, False), (at_beginning_line, False), (at_beginning, False), + (at_boundary, False), (at_boundary, True), + (at_end, False), (at_end_line, False), (at_end_string, False), + (at_loc_boundary, False), (at_loc_boundary, True), (at_uni_boundary, False), + (at_uni_boundary, True) +] Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Fri Aug 12 12:55:47 2005 @@ -8,43 +8,72 @@ def test_is_uni_linebreak(space): for char in ["\n", "\r"]: - assert space.is_true(isre.is_uni_linebreak(space, space.wrap(char))) - assert space.is_true(isre.is_uni_linebreak(space, space.newunicode([ord(char)]))) + assert isre.is_uni_linebreak(space, space.wrap(char)) + assert isre.is_uni_linebreak(space, space.newunicode([ord(char)])) for char in [" ", "b"]: - assert not space.is_true(isre.is_uni_linebreak(space, space.wrap(char))) - assert not space.is_true(isre.is_uni_linebreak(space, space.newunicode([ord(char)]))) - assert space.is_true(isre.is_uni_linebreak(space, space.newunicode([8232]))) + assert not isre.is_uni_linebreak(space, space.wrap(char)) + assert not isre.is_uni_linebreak(space, space.newunicode([ord(char)])) + assert isre.is_uni_linebreak(space, space.newunicode([8232])) def test_is_uni_word(space): for char in ["a", "_", "\xe4"]: - assert space.is_true(isre.is_uni_word(space, space.wrap(char))) + assert isre.is_uni_word(space, space.wrap(char)) for char in ["a", "_", "\xe4", u"\u00e4", u"\u03a0"]: - assert space.is_true(isre.is_uni_word(space, space.newunicode([ord(char)]))) + assert isre.is_uni_word(space, space.newunicode([ord(char)])) for char in [".", " "]: - assert not space.is_true(isre.is_uni_word(space, space.wrap(char))) + assert not isre.is_uni_word(space, space.wrap(char)) for char in [".", " ", EM_SPACE]: - assert not space.is_true(isre.is_uni_word(space, space.newunicode([ord(char)]))) + assert not isre.is_uni_word(space, space.newunicode([ord(char)])) def test_is_loc_word(space): # should also test chars actually affected by locale (between 128 and 256) for char in ["1", "2"]: - assert space.is_true(isre.is_loc_word(space, space.wrap(char))) - assert space.is_true(isre.is_loc_word(space, space.newunicode([ord(char)]))) + assert isre.is_loc_word(space, space.wrap(char)) + assert isre.is_loc_word(space, space.newunicode([ord(char)])) for char in [" ", u".", u"\u03a0"]: - assert not space.is_true(isre.is_loc_word(space, space.newunicode([ord(char)]))) + assert not isre.is_loc_word(space, space.newunicode([ord(char)])) def test_is_uni_digit(space): for char in ["0", "9"]: - assert space.is_true(isre.is_uni_digit(space, space.wrap(char))) + assert isre.is_uni_digit(space, space.wrap(char)) for char in ["0", "9", INDIAN_DIGIT]: - assert space.is_true(isre.is_uni_digit(space, space.newunicode([ord(char)]))) + assert isre.is_uni_digit(space, space.newunicode([ord(char)])) for char in [" ", "s"]: - assert not space.is_true(isre.is_uni_digit(space, space.wrap(char))) + assert not isre.is_uni_digit(space, space.wrap(char)) def test_is_uni_space(space): for char in [" ", "\t"]: - assert space.is_true(isre.is_uni_space(space, space.wrap(char))) + assert isre.is_uni_space(space, space.wrap(char)) for char in ["\v", "\n", EM_SPACE]: - assert space.is_true(isre.is_uni_space(space, space.newunicode([ord(char)]))) + assert isre.is_uni_space(space, space.newunicode([ord(char)])) for char in ["a", "1"]: - assert not space.is_true(isre.is_uni_space(space, space.wrap(char))) + assert not isre.is_uni_space(space, space.wrap(char)) + +def test_at_beginning(space): + assert isre.at_beginning(space, + isre.MatchContext(space, space.wrap(""), 0, 0)) + assert not isre.at_beginning(space, + isre.MatchContext(space, space.wrap("a"), 1, 1)) + +def test_at_beginning_line(space): + assert isre.at_beginning_line(space, + isre.MatchContext(space, space.wrap(""), 0, 0)) + assert isre.at_beginning_line(space, + isre.MatchContext(space, space.wrap("\na"), 1, 3)) + assert not isre.at_beginning_line(space, + isre.MatchContext(space, space.wrap("a"), 1, 2)) + +def test_at_end(space): + for string, pos, end in [("", 0, 0), ("a", 1, 1), ("a\n", 1, 2)]: + assert isre.at_end(space, + isre.MatchContext(space, space.wrap(string), pos, end)) + assert not isre.at_end(space, + isre.MatchContext(space, space.wrap("a"), 0, 1)) + +def test_at_boundary(space): + for string, pos, end in [("a.", 1, 2), (".a", 1, 2)]: + assert isre.at_boundary(space, + isre.MatchContext(space, space.wrap(string), pos, end)) + for string, pos, end in [(".", 0, 1), (".", 1, 1), ("ab", 1, 2)]: + assert not isre.at_boundary(space, + isre.MatchContext(space, space.wrap(string), pos, end)) From rxe at codespeak.net Fri Aug 12 13:29:57 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 12 Aug 2005 13:29:57 +0200 (CEST) Subject: [pypy-svn] r16003 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050812112957.2CB0327B61@code1.codespeak.net> Author: rxe Date: Fri Aug 12 13:29:54 2005 New Revision: 16003 Modified: pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/test/test_lltype.py Log: Special cases for float reprs. For nan and inf, not sure totally right, need to speak to the llvm guys. Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Fri Aug 12 13:29:54 2005 @@ -349,14 +349,27 @@ # __________________________________________________________ # Primitive stuff + def float_to_str(self, value): + repr = "%f" % value + # llvm requires a . when using e notation + if "e" in repr and "." not in repr: + repr = repr.replace("e", ".0e") + elif repr in ["inf", "nan"]: + # Need hex repr + import struct + packed = struct.pack("d", value) + repr = "0x" + "".join([("%02x" % ord(ii)) for ii in packed]) + return repr + def primitive_to_str(self, type_, value): - #XXX Need to watch for special float values (inf, 2E200) if type_ is lltype.Bool: repr = str(value).lower() #False --> false elif type_ is lltype.Char: repr = str(ord(value)) elif type_ is lltype.UniChar: repr = str(ord(value)) + elif type_ is lltype.Float: + repr = self.float_to_str(value) else: repr = str(value) return repr Modified: pypy/dist/pypy/translator/llvm2/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_lltype.py Fri Aug 12 13:29:54 2005 @@ -213,3 +213,31 @@ return s.a f = compile_function(array_constant, []) assert f() == array_constant() + +def test_floats(): + " test pbc of floats " + F = lltype.GcStruct("f", + ('f1', lltype.Float), + ('f2', lltype.Float), + ('f3', lltype.Float), + ('f4', lltype.Float), + ('f5', lltype.Float), + ) + floats = lltype.malloc(F) + floats.f1 = 1.25 + floats.f2 = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.252984 + floats.f3 = float(29050000000000000000000000000000000000000000000000000000000000000000) + floats.f4 = float("inf") + floats.f5 = float("nan") + f = float("nan") + def floats_fn(): + res = floats.f1 == 1.25 + res += floats.f2 > 1e100 + res += floats.f3 > 1e50 + # XXX Need to find out more about these in llvm + #res += floats.f4 > 1e200 + #res += floats.f5 == f + return res + + f = compile_function(floats_fn, []) + assert f() == floats_fn() From ericvrp at codespeak.net Fri Aug 12 15:09:21 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 12 Aug 2005 15:09:21 +0200 (CEST) Subject: [pypy-svn] r16005 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050812130921.3270627B64@code1.codespeak.net> Author: ericvrp Date: Fri Aug 12 15:09:20 2005 New Revision: 16005 Modified: pypy/dist/pypy/translator/llvm2/test/test_seq.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: more tests Modified: pypy/dist/pypy/translator/llvm2/test/test_seq.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_seq.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_seq.py Fri Aug 12 15:09:20 2005 @@ -12,6 +12,7 @@ assert f() == 42 def test_array1(self): + py.test.skip("unknown raison") f = compile_function(llvmsnippet.array_simple1, [int]) assert f(1) == 10 assert f(-42) == -420 Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Fri Aug 12 15:09:20 2005 @@ -2,7 +2,7 @@ import py from py.test import raises from pypy.translator.test import snippet -from pypy.rpython.rarithmetic import r_uint +from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift from pypy.translator.llvm2.genllvm import compile_function @@ -341,7 +341,56 @@ f = compile_function(int_abs_, [int]) for i in (-25, 0, 75): assert f(i) == int_abs_(i) - + +def test_int_add_ovf(): + py.test.skip("int add incorrect overflow test") + def add_func(i): + try: + return ovfcheck(i + 1) + except OverflowError: + return 123 + f = compile_function(add_func, [int]) + assert f(0) == add_func(0) + assert f(0) == 1 + assert f(sys.maxint) == add_func(sys.maxint) + assert f(sys.maxint) == 123 + +def test_int_sub_ovf(): + py.test.skip("ovf test") + def sub_func(i): + try: + return ovfcheck(i - 1) + except OverflowError: + return 123 + f = compile_function(sub_func, [int]) + assert f(0) == sub_func(0) + assert f(0) == 1 + assert f(sys.maxint) == sub_func(sys.maxint) + assert f(sys.maxint) == 123 + +def test_int_div_ovf_zer(): + py.test.skip("ovf test") + f = compile_function(snippet.div_func) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_mod_ovf_zer(): + py.test.skip("ovf test") + f = compile_function(snippet.mod_func) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_rshift_val(): + py.test.skip("ovf test") + f = compile_function(snippet.rshift_func) + raises(ValueError, fn, -1) + +def test_int_lshift_ovf_val(): + py.test.skip("ovf test") + f = compile_function(snippet.lshift_func) + raises(ValueError, fn, -1) + raises(OverflowError, fn, 1) + def test_float_abs(): def float_abs_(n): return abs(n) From ericvrp at codespeak.net Fri Aug 12 15:09:55 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 12 Aug 2005 15:09:55 +0200 (CEST) Subject: [pypy-svn] r16006 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050812130955.70F4027B64@code1.codespeak.net> Author: ericvrp Date: Fri Aug 12 15:09:54 2005 New Revision: 16006 Modified: pypy/dist/pypy/translator/llvm2/module/support.py Log: some exception raising operations Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 12 15:09:54 2005 @@ -62,36 +62,49 @@ """ % locals()) -#binary with ZeroDivisionError only -for func_inst in "floordiv_zer:div mod_zer:rem".split(): - func, inst = func_inst.split(':') - for type_ in "int uint".split(): - extfunctions["%%%(type_)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ -internal fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { +#error-checking-code - ;zerodiv test - %%cond = seteq %(type_)s %%y, 0 +zer_test = """ + %%cond = seteq %s %%y, 0 br bool %%cond, label %%is_0, label %%is_not_0 is_0: call fastcc void %%__prepare_ZeroDivisionError() unwind - + is_not_0: - %%z = %(inst)s %(type_)s %%x, %%y - ret %(type_)s %%z -} +""" +int_zer_test = zer_test % ('int',) +double_zer_test = zer_test % ('double',) -""" % locals()) +#overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) OK else _OVF() +#note: XXX this hardcoded int32 minint value is used because of a pre llvm1.6 bug! int_ovf_test = """ - %cond2 = setne int %x, -2147483648 ;-sys.maxint-1 + %cond2 = setne int %x, -2147483648 br bool %cond2, label %return_block, label %ovf ovf: call fastcc void %__prepare_OverflowError() unwind """ + +#binary with ZeroDivisionError only + +for func_inst in "floordiv_zer:div mod_zer:rem".split(): + func, inst = func_inst.split(':') + for type_ in "int uint".split(): + type_zer_test = zer_test % type_ + extfunctions["%%%(type_)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ +internal fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { + %(type_zer_test)s + %%z = %(inst)s %(type_)s %%x, %%y + ret %(type_)s %%z +} + +""" % locals()) + + #unary with OverflowError only extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """ @@ -119,77 +132,72 @@ """ % locals()) -#XXX TODO +#binary with OverflowError only -#extfunctions["%float_pow"] = ((), """ -#fastcc double %float_pow(double %x, double %y) { -# ; XXX ERROR float_pow exception raising not implemented -# %r = call ccc double %pow(double %x, double %y) -# ret double %r -#} -# -#""") -# -#extfunctions["%float_mod"] = ((), """ -#fastcc double %float_mod(double %x, double %y) { -# ; XXX ERROR float_mod exception raising not implemented -# %r = call ccc double %fmod(double %x, double %y) -# ret double %r -#} -# -#""") -# -#for func in 'float_abs float_sub float_add float_mul float_div'.split(): -# extfunctions["%" + func] = ((), """ -#fastcc double %%%(func)s(double %%x, double %%y) { -# ; XXX ERROR %(func)s exception raising not implemented -# ret double 0.0 -#} -# -#""" % locals()) -# -#for func in 'int_abs int_sub int_add int_mul int_div int_mod int_add_ovf int_sub_ovf int_mul_ovf int_floordiv_ovf int_mod_ovf int_floordiv_ovf_zer int_mod_ovf_zer int_lshift_ovf int_lshift_ovf_val int_rshift_val int_lshift_val'.split(): -# extfunctions["%" + func] = ((), """ -#fastcc int %%%(func)s(int %%x, int %%y) { -# ; XXX ERROR %(func)s exception raising not implemented -# ret int 0 -#} -# -#""" % locals()) - - -#XXX TODO - -#overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) ok else _OVF() - -#binary with overflow -#define OP_INT_ADD_OVF(x,y,r,err) \ -#define OP_INT_SUB_OVF(x,y,r,err) \ -#define OP_INT_MUL_OVF(x,y,r,err) \ -#define OP_INT_MUL_OVF(x,y,r,err) \ -#define OP_INT_FLOORDIV_OVF(x,y,r,err) \ -#define OP_INT_MOD_OVF(x,y,r,err) \ - -#binary with overflow and zerodiv -#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \ -#define OP_INT_MOD_OVF_ZER(x,y,r,err) \ - -#shift -#define OP_INT_LSHIFT_OVF(x,y,r,err) \ -#define OP_INT_LSHIFT_OVF_VAL(x,y,r,err) \ -#define OP_INT_RSHIFT_VAL(x,y,r,err) \ -#define OP_INT_LSHIFT_VAL(x,y,r,err) \ - - -#DONE - -#binary with zerodivisionerror only -#define OP_INT_FLOORDIV_ZER(x,y,r,err) \ -#define OP_UINT_FLOORDIV_ZER(x,y,r,err) \ -#define OP_INT_MOD_ZER(x,y,r,err) \ -#define OP_UINT_MOD_ZER(x,y,r,err) \ - -#unary with overflow only -#define OP_INT_ABS_OVF(x,r,err) \ untested -#define OP_INT_NEG_OVF(x,r,err) \ untested +extfunctions["%int_add_ovf"] = (("%__prepare_OverflowError",), """ +internal fastcc int %%int_add_ovf(int %%x, int %%y) { + %%t = add int %%x, %%y + %(int_ovf_test)s +return_block: + ; XXX: TEST int_add_ovf checking + ret int %%t +} +""" % locals()) + +extfunctions["%int_sub_ovf"] = (("%__prepare_OverflowError",), """ +internal fastcc int %%int_sub_ovf(int %%x, int %%y) { + %%t = sub int %%x, %%y + %(int_ovf_test)s +return_block: + ; XXX: TEST int_sub_ovf checking + ret int %%t +} +""" % locals()) +extfunctions["%int_mul_ovf"] = (("%__prepare_OverflowError",), """ +internal fastcc int %%int_mul_ovf(int %%x, int %%y) { + %%t = mul int %%x, %%y + %(int_ovf_test)s +return_block: + ; XXX: TEST int_mul_ovf checking + ret int %%t +} +""" % locals()) + + +#binary with OverflowError and ValueError + +extfunctions["%int_lshift_ovf_val"] = (("%__prepare_OverflowError","%__prepare_ValueError"), """ +internal fastcc int %%int_lshift_ovf_val(int %%x, int %%y) { + %%t = shl int %%x, ubyte %%y + %(int_ovf_test)s +return_block: + ; XXX: TODO int_lshift_ovf_val checking VAL + ret int %%t +} +""" % locals()) + + +#binary with OverflowError and ZeroDivisionError + +extfunctions["%int_floordiv_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ +internal fastcc int %%int_floordiv_zer_val(int %%x, int %%y) { + %(int_zer_test)s + %%t = div int %%x, %%y + %(int_ovf_test)s +return_block: + ; XXX: TEST int_floordiv_zer_val checking + ret int %%t +} +""" % locals()) + +extfunctions["%int_mod_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ +internal fastcc int %%int_mod_ovf_zer(int %%x, int %%y) { + %(int_zer_test)s + %%t = rem int %%x, ubyte %%y + %(int_ovf_test)s +return_block: + ; XXX: TEST int_mod_ovf_zer checking + ret int %%t +} +""" % locals()) From ericvrp at codespeak.net Fri Aug 12 15:10:50 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 12 Aug 2005 15:10:50 +0200 (CEST) Subject: [pypy-svn] r16007 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050812131050.34AF327B64@code1.codespeak.net> Author: ericvrp Date: Fri Aug 12 15:10:49 2005 New Revision: 16007 Modified: pypy/dist/pypy/translator/llvm2/funcnode.py Log: fix to prevent multiple function definitions Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Fri Aug 12 15:10:49 2005 @@ -27,12 +27,12 @@ returntype = self.db.repr_arg_type(self.type_.RESULT) inputargtypes = self.db.repr_arg_type_multi(self.type_._trueargs()) codewriter.funcdef(self.ref, returntype, inputargtypes) - + class FuncNode(ConstantLLVMNode): def __init__(self, db, value): self.db = db self.value = value - self.ref = "%" + value.graph.name + self.ref = self.make_ref('%', value.graph.name) self.graph = value.graph remove_same_as(self.graph) remove_double_links(self.db._translator, self.graph) From ericvrp at codespeak.net Fri Aug 12 15:12:07 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 12 Aug 2005 15:12:07 +0200 (CEST) Subject: [pypy-svn] r16008 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050812131207.7314027B64@code1.codespeak.net> Author: ericvrp Date: Fri Aug 12 15:12:06 2005 New Revision: 16008 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py Log: XXX bypass for phi nodes where the targetvariable has the same name as at least one of the referred variables! This probably should not be in the graph! Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Fri Aug 12 15:12:06 2005 @@ -93,6 +93,9 @@ def phi(self, targetvar, type_, refs, blocknames): assert targetvar.startswith('%') assert refs and len(refs) == len(blocknames), "phi node requires blocks" + for ref in refs: + if targetvar == ref: #some nodes break SSA-form otherwise?!? + return mergelist = ", ".join( ["[%s, %%%s]" % item for item in zip(refs, blocknames)]) From nik at codespeak.net Fri Aug 12 17:03:36 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 12 Aug 2005 17:03:36 +0200 (CEST) Subject: [pypy-svn] r16011 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050812150336.EA87927B6D@code1.codespeak.net> Author: nik Date: Fri Aug 12 17:03:34 2005 New Revision: 16011 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_interp_sre.py Log: moved charset (character class) evaluation to interp-level. quite a bit of uglyness has accumulated now due to the app-level/interp-level split. this will get better over time ... Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Fri Aug 12 17:03:34 2005 @@ -18,6 +18,7 @@ } interpleveldefs = { + '_check_charset': 'interp_sre.check_charset', '_at_dispatch': 'interp_sre.at_dispatch', '_category_dispatch': 'interp_sre.category_dispatch', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 12 17:03:34 2005 @@ -538,7 +538,6 @@ def __init__(self): self.executing_contexts = {} - self.set_dispatcher = _CharsetDispatcher() def match(self, context): """Returns True if the current context matches, False if it doesn't and @@ -669,7 +668,9 @@ return skip = ctx.peek_code(1) ctx.skip_code(2) # set op pointer to the set code - if not self.check_charset(ctx, decorate(ord(ctx.peek_char()))): + char = decorate(ord(ctx.peek_char())) + if not _sre._check_charset(ctx.pattern_codes[ctx.code_position:], char, + ctx.state.string, ctx.string_position): ctx.has_matched = False return ctx.skip_code(skip - 1) @@ -1023,18 +1024,7 @@ def unknown(self, ctx): #self._log(ctx, "UNKNOWN", ctx.peek_code()) raise RuntimeError("Internal re error. Unknown opcode: %s" % ctx.peek_code()) - - def check_charset(self, ctx, char): - """Checks whether a character matches set of arbitrary length. Assumes - the code pointer is at the first member of the set.""" - self.set_dispatcher.reset(char) - save_position = ctx.code_position - result = None - while result is None: - result = self.set_dispatcher.dispatch(ctx.peek_code(), ctx) - ctx.code_position = save_position - return result - + def count_repetitions(self, ctx, maxcount): """Returns the number of repetitions of a single item, starting from the current string position. The code pointer is expected to point to a @@ -1071,74 +1061,6 @@ _OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") -class _CharsetDispatcher(_Dispatcher): - - def reset(self, char): - self.char = char - self.ok = True - - def set_failure(self, ctx): - return not self.ok - def set_literal(self, ctx): - # - if ctx.peek_code(1) == self.char: - return self.ok - else: - ctx.skip_code(2) - def set_category(self, ctx): - # - if _sre._category_dispatch(ctx.peek_code(1), ctx.peek_char()): - return self.ok - else: - ctx.skip_code(2) - def set_charset(self, ctx): - # (16 bits per code word) - char_code = self.char - ctx.skip_code(1) # point to beginning of bitmap - if CODESIZE == 2: - if char_code < 256 and ctx.peek_code(char_code >> 4) \ - & (1 << (char_code & 15)): - return self.ok - ctx.skip_code(16) # skip bitmap - else: - if char_code < 256 and ctx.peek_code(char_code >> 5) \ - & (1 << (char_code & 31)): - return self.ok - ctx.skip_code(8) # skip bitmap - def set_range(self, ctx): - # - if ctx.peek_code(1) <= self.char <= ctx.peek_code(2): - return self.ok - ctx.skip_code(3) - def set_negate(self, ctx): - self.ok = not self.ok - ctx.skip_code(1) - def set_bigcharset(self, ctx): - # <256 blockindices> - char_code = self.char - count = ctx.peek_code(1) - ctx.skip_code(2) - if char_code < 65536: - block_index = char_code >> 8 - # NB: there are CODESIZE block indices per bytecode - a = array.array("B") - a.fromstring(array.array(CODESIZE == 2 and "H" or "I", - [ctx.peek_code(block_index / CODESIZE)]).tostring()) - block = a[block_index % CODESIZE] - ctx.skip_code(256 / CODESIZE) # skip block indices - block_value = ctx.peek_code(block * (32 / CODESIZE) - + ((char_code & 255) >> (CODESIZE == 2 and 4 or 5))) - if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): - return self.ok - else: - ctx.skip_code(256 / CODESIZE) # skip block indices - ctx.skip_code(count * (32 / CODESIZE)) # skip blocks - def unknown(self, ctx): - return False - -_CharsetDispatcher.build_dispatch_table(OPCODES, "set_") - - def _log(message): if 0: print message Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 12 17:03:34 2005 @@ -1,4 +1,7 @@ from pypy.interpreter.baseobjspace import ObjSpace +# XXX is it allowed to import app-level module like this? +from pypy.module._sre.app_info import CODESIZE +from pypy.module.array.app_array import array #### Category helpers @@ -89,11 +92,14 @@ class MatchContext: # XXX This is not complete. It's tailored to at dispatch currently. - def __init__(self, space, w_string, string_position, end): + def __init__(self, space, pattern_codes, w_string, string_position, end): self.space = space + self.pattern_codes = pattern_codes self.w_string = w_string self.string_position = string_position self.end = end + self.code_position = 0 + self.set_ok = True # XXX maybe get rid of this def peek_char(self, peek=0): return self.space.getitem(self.w_string, @@ -102,6 +108,12 @@ def remaining_chars(self): return self.end - self.string_position + def peek_code(self, peek=0): + return self.pattern_codes[self.code_position + peek] + + def skip_code(self, skip_count): + self.code_position += skip_count + def at_beginning(self): return self.string_position == 0 @@ -126,7 +138,7 @@ atcode = space.int_w(w_atcode) if atcode >= len(at_dispatch_table): return space.newbool(False) - context = MatchContext(space, w_string, space.int_w(w_string_position), + context = MatchContext(space, [], w_string, space.int_w(w_string_position), space.int_w(w_end)) function, negate = at_dispatch_table[atcode] result = function(space, context) @@ -144,19 +156,19 @@ def at_end(space, ctx): return ctx.at_end() or (ctx.remaining_chars() == 1 and ctx.at_linebreak()) -def at_end_line(self, ctx): +def at_end_line(space, ctx): return ctx.at_linebreak() or ctx.at_end() -def at_end_string(self, ctx): +def at_end_string(space, ctx): return ctx.at_end() -def at_boundary(self, ctx): +def at_boundary(space, ctx): return ctx.at_boundary(is_word) -def at_loc_boundary(self, ctx): +def at_loc_boundary(space, ctx): return ctx.at_boundary(is_loc_word) -def at_uni_boundary(self, ctx): +def at_uni_boundary(space, ctx): return ctx.at_boundary(is_uni_word) # Maps opcodes by indices to (function, negate) tuples. @@ -167,3 +179,95 @@ (at_loc_boundary, False), (at_loc_boundary, True), (at_uni_boundary, False), (at_uni_boundary, True) ] + +##### Charset evaluation + +def check_charset(space, w_pattern_codes, w_char_code, w_string, w_string_position): + """Checks whether a character matches set of arbitrary length. Currently + assumes the set starts at the first member of pattern_codes.""" + # XXX temporary ugly method signature until we can call this from + # interp-level only + pattern_codes_w = space.unpackiterable(w_pattern_codes) + pattern_codes = [space.int_w(code) for code in pattern_codes_w] + char_code = space.int_w(w_char_code) + context = MatchContext(space, pattern_codes, w_string, + space.int_w(w_string_position), space.int_w(space.len(w_string))) + result = None + while result is None: + opcode = context.peek_code() + if opcode >= len(set_dispatch_table): + return space.newbool(False) + function = set_dispatch_table[opcode] + result = function(space, context, char_code) + return space.newbool(result) + +def set_failure(space, ctx, char_code): + return not ctx.set_ok + +def set_literal(space, ctx, char_code): + # + if ctx.peek_code(1) == char_code: + return ctx.set_ok + else: + ctx.skip_code(2) + +def set_category(space, ctx, char_code): + # + if space.is_true( + category_dispatch(space, space.wrap(ctx.peek_code(1)), ctx.peek_char())): + return ctx.set_ok + else: + ctx.skip_code(2) + +def set_charset(space, ctx, char_code): + # (16 bits per code word) + ctx.skip_code(1) # point to beginning of bitmap + if CODESIZE == 2: + if char_code < 256 and ctx.peek_code(char_code >> 4) \ + & (1 << (char_code & 15)): + return ctx.set_ok + ctx.skip_code(16) # skip bitmap + else: + if char_code < 256 and ctx.peek_code(char_code >> 5) \ + & (1 << (char_code & 31)): + return ctx.set_ok + ctx.skip_code(8) # skip bitmap + +def set_range(space, ctx, char_code): + # + if ctx.peek_code(1) <= char_code <= ctx.peek_code(2): + return ctx.set_ok + ctx.skip_code(3) + +def set_negate(space, ctx, char_code): + ctx.set_ok = not ctx.set_ok + ctx.skip_code(1) + +def set_bigcharset(space, ctx, char_code): + # <256 blockindices> + # XXX this function probably needs a makeover + count = ctx.peek_code(1) + ctx.skip_code(2) + if char_code < 65536: + block_index = char_code >> 8 + # NB: there are CODESIZE block indices per bytecode + # XXX can we really use array here? + a = array("B") + a.fromstring(array(CODESIZE == 2 and "H" or "I", + [ctx.peek_code(block_index / CODESIZE)]).tostring()) + block = a[block_index % CODESIZE] + ctx.skip_code(256 / CODESIZE) # skip block indices + block_value = ctx.peek_code(block * (32 / CODESIZE) + + ((char_code & 255) >> (CODESIZE == 2 and 4 or 5))) + if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): + return ctx.set_ok + else: + ctx.skip_code(256 / CODESIZE) # skip block indices + ctx.skip_code(count * (32 / CODESIZE)) # skip blocks + +set_dispatch_table = [ + set_failure, None, None, None, None, None, None, None, None, + set_category, set_charset, set_bigcharset, None, None, None, + None, None, None, None, set_literal, None, None, None, None, + None, None, set_negate, set_range +] Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Fri Aug 12 17:03:34 2005 @@ -51,29 +51,29 @@ def test_at_beginning(space): assert isre.at_beginning(space, - isre.MatchContext(space, space.wrap(""), 0, 0)) + isre.MatchContext(space, [], space.wrap(""), 0, 0)) assert not isre.at_beginning(space, - isre.MatchContext(space, space.wrap("a"), 1, 1)) + isre.MatchContext(space, [], space.wrap("a"), 1, 1)) def test_at_beginning_line(space): assert isre.at_beginning_line(space, - isre.MatchContext(space, space.wrap(""), 0, 0)) + isre.MatchContext(space, [], space.wrap(""), 0, 0)) assert isre.at_beginning_line(space, - isre.MatchContext(space, space.wrap("\na"), 1, 3)) + isre.MatchContext(space, [], space.wrap("\na"), 1, 3)) assert not isre.at_beginning_line(space, - isre.MatchContext(space, space.wrap("a"), 1, 2)) + isre.MatchContext(space, [], space.wrap("a"), 1, 2)) def test_at_end(space): for string, pos, end in [("", 0, 0), ("a", 1, 1), ("a\n", 1, 2)]: assert isre.at_end(space, - isre.MatchContext(space, space.wrap(string), pos, end)) + isre.MatchContext(space, [], space.wrap(string), pos, end)) assert not isre.at_end(space, - isre.MatchContext(space, space.wrap("a"), 0, 1)) + isre.MatchContext(space, [], space.wrap("a"), 0, 1)) def test_at_boundary(space): for string, pos, end in [("a.", 1, 2), (".a", 1, 2)]: assert isre.at_boundary(space, - isre.MatchContext(space, space.wrap(string), pos, end)) + isre.MatchContext(space, [], space.wrap(string), pos, end)) for string, pos, end in [(".", 0, 1), (".", 1, 1), ("ab", 1, 2)]: assert not isre.at_boundary(space, - isre.MatchContext(space, space.wrap(string), pos, end)) + isre.MatchContext(space, [], space.wrap(string), pos, end)) From cfbolz at codespeak.net Fri Aug 12 17:41:50 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 12 Aug 2005 17:41:50 +0200 (CEST) Subject: [pypy-svn] r16012 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050812154150.B891927B61@code1.codespeak.net> Author: cfbolz Date: Fri Aug 12 17:41:50 2005 New Revision: 16012 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/test/test_gc.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: oops. get_contained_pointers gives _pointers_ to the objects, not the addresses itself. Moved the mark and sweep test to test_gc and added a new test that tests the fix. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Fri Aug 12 17:41:50 2005 @@ -70,7 +70,7 @@ pointer = pointers.pop() if pointer == NULL: break - objects.append(pointer) + objects.append(pointer.address[0]) gc_info.signed[0] = 1 newmo = AddressLinkedList() while 1: #sweep Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 12 17:41:50 2005 @@ -4,6 +4,8 @@ from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL from pypy.rpython.memory.simulator import MemorySimulatorError +from pypy.rpython.memory import gclltype +from pypy.rpython.memory.test.test_llinterpsim import interpret def test_free_non_gc_object(): @@ -90,3 +92,37 @@ py.test.raises(MemorySimulatorError, "addr1.signed[0]") py.test.raises(MemorySimulatorError, "addr2.signed[0]") + def test_llinterp_lists(self): + from pypy.rpython.memory.lladdress import simulator + gclltype.create_gc = gclltype.create_mark_sweep_gc + curr = simulator.current_size + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = [1] * 10 + j = 0 + while j < 20: + j += 1 + a.append(j) + res = interpret(malloc_a_lot, []) + assert simulator.current_size - curr < 16000 + print "size before: %s, size after %s" % (curr, simulator.current_size) + + def test_llinterp_tuples(self): + from pypy.rpython.memory.lladdress import simulator + gclltype.create_gc = gclltype.create_mark_sweep_gc + curr = simulator.current_size + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = (1, 2, i) + b = [a] * 10 + j = 0 + while j < 20: + j += 1 + b.append((1, j, i)) + res = interpret(malloc_a_lot, []) + assert simulator.current_size - curr < 16000 + print "size before: %s, size after %s" % (curr, simulator.current_size) Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Fri Aug 12 17:41:50 2005 @@ -386,19 +386,3 @@ assert ''.join(res.chars) == '-123' -def test_mark_sweep_gc(): - from pypy.rpython.memory.lladdress import simulator - gclltype.create_gc = gclltype.create_mark_sweep_gc - curr = simulator.current_size - def malloc_a_lot(): - i = 0 - while i < 10: - i += 1 - a = [1] * 10 - j = 0 - while j < 20: - j += 1 - a.append(j) - res = interpret(malloc_a_lot, []) - assert simulator.current_size - curr < 16000 - print "size before: %s, size after %s" % (curr, simulator.current_size) From adim at codespeak.net Fri Aug 12 18:11:51 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Fri, 12 Aug 2005 18:11:51 +0200 (CEST) Subject: [pypy-svn] r16013 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050812161151.45DFB27B64@code1.codespeak.net> Author: adim Date: Fri Aug 12 18:11:48 2005 New Revision: 16013 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/pythonutil.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: moved toward a RPYTHON implementation of astbuilder. The last checked-in version of astbuilder.py was nearly fully usable (tests passed on all stdlib files). At this point, we're still missing the following features : - lienos are not set - encoding declarations are not handled (actually they're not part of the AST) - not a feature, but astbuilder also needs to be refactored The changes made for this checkin are basically : - don't use eval() builtin anymore in eval_number() and eval_string(). The replacement implementation is incomplete though, so it needs to be finished (esp. for raw/unicode strings, and 0x-like numbers) - put assert isinstance() in a lot of places to help the annotator - provide a RPYTHON version of parse_fpdef(), but this version can't be used with the current compiler package. (the problem if for functions defined as in "def f(a, b, (c,d), e): pass" because we must build nested tuples for the argument list, and that makes it un-annotatble. At this point (when using the RPYTHON's version of parse_fpdef), we still have 8 functions that take or return a SomeObject instance. Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Fri Aug 12 18:11:48 2005 @@ -10,7 +10,6 @@ DEBUG_MODE = 0 - ### Parsing utilites ################################################# def parse_except_clause(tokens): """parses 'except' [test [',' test]] ':' suite @@ -22,7 +21,7 @@ while clause_length < len(tokens): token = tokens[clause_length] if isinstance(token, TokenObject) and \ - (token.value == 'except' or token.value == 'else'): + (token.get_value() == 'except' or token.get_value() == 'else'): break clause_length += 1 # if clause_length >= len(tokens): @@ -44,7 +43,10 @@ this function doesn't assume that the list ends after the last 'NAME' element """ - name = tokens[0].value + first = tokens[0] + assert isinstance(first, TokenObject) + name = first.get_value() + assert isinstance(name, str) l = len(tokens) index = 1 for index in range(1, l, 2): @@ -52,7 +54,11 @@ assert isinstance(token, TokenObject) if token.name != tok.DOT: break - name = name + '.' + tokens[index+1].value + token = tokens[index+1] + assert isinstance(token, TokenObject) + name += '.' + value = token.get_value() + name += value return (index, name) def parse_argument(tokens): @@ -96,7 +102,65 @@ return arguments, stararg_token, dstararg_token -def parse_fpdef(tokens): +class BaseItem: + """base item class""" + +class SimpleItem(BaseItem): + def __init__(self, attrname): + self.attrname = attrname + +class TupleItem(BaseItem): + def __init__(self, value): + self.value = value + + def append(self, element): + assert isinstance(element, BaseItem) + self.value.append(element) + + def pop(self): + return self.value.pop() + +def rpython_parse_fpdef(tokens): + """fpdef: fpdef: NAME | '(' fplist ')' + fplist: fpdef (',' fpdef)* [','] + + This intend to be a RPYTHON compliant implementation of _parse_fpdef, + but it can't work with the default compiler. + XXX: incomplete + """ + stack = [] # list of lists + tokens_read = 0 + to_be_closed = 1 # number of parenthesis to be closed + result = None + while to_be_closed > 0: + token = tokens[tokens_read] + tokens_read += 1 + if isinstance(token, TokenObject) and token.name == tok.COMMA: + continue + elif isinstance(token, TokenObject) and token.name == tok.LPAR: + stack.append(TupleItem([])) + to_be_closed += 1 + elif isinstance(token, TokenObject) and token.name == tok.RPAR: + to_be_closed -= 1 + elt = stack.pop() + if to_be_closed > 0: + top = stack[-1] + assert isinstance(top, TupleItem) + top.append(elt) + else: + # stack.append(tuple(elt)) + break + else: + assert isinstance(token, TokenObject) + if to_be_closed == 1: + stack.append(SimpleItem(token.get_value())) + else: + top = stack[-1] + assert isinstance(top, TupleItem) + top.append(SimpleItem(token.get_value())) + return tokens_read, stack + +def working_parse_fpdef(tokens): """fpdef: fpdef: NAME | '(' fplist ')' fplist: fpdef (',' fpdef)* [','] """ @@ -122,10 +186,13 @@ stack.append(tuple(elt)) else: assert isinstance(token, TokenObject) - stack[-1].append(token.value) + stack[-1].append(token.get_value()) assert len(stack) == 1, "At the end of parse_fpdef, len(stack) should be 1, got %s" % stack return tokens_read, tuple(stack[0]) +# parse_fpdef = rpython_parse_fpdef +parse_fpdef = working_parse_fpdef + def parse_arglist(tokens): """returns names, defaults, flags""" l = len(tokens) @@ -137,7 +204,7 @@ cur_token = tokens[index] index += 1 ## if isinstance(cur_token, FPListObject): -## names.append(cur_token.value) +## names.append(cur_token.get_value()) if not isinstance(cur_token, TokenObject): # XXX: think of another way to write this test defaults.append(cur_token) @@ -152,9 +219,10 @@ elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: if cur_token.name == tok.STAR: cur_token = tokens[index] + assert isinstance(cur_token, TokenObject) index += 1 if cur_token.name == tok.NAME: - names.append(cur_token.value) + names.append(cur_token.get_value()) flags |= consts.CO_VARARGS index += 1 if index >= l: @@ -169,8 +237,9 @@ raise ValueError("Unexpected token: %s" % cur_token) cur_token = tokens[index] index += 1 + assert isinstance(cur_token, TokenObject) if cur_token.name == tok.NAME: - names.append(cur_token.value) + names.append(cur_token.get_value()) flags |= consts.CO_VARKEYWORDS index += 1 else: @@ -178,7 +247,7 @@ if index < l: raise ValueError("unexpected token: %s" % tokens[index]) elif cur_token.name == tok.NAME: - names.append(cur_token.value) + names.append(cur_token.get_value()) return names, defaults, flags @@ -191,19 +260,42 @@ ifs = [] index = 0 while index < len(tokens): - if tokens[index].value == 'for': + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + check + if token.get_value() == 'for': index += 1 # skip 'for' ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) index += 2 # skip 'in' iterable = tokens[index] index += 1 - while index < len(tokens) and tokens[index].value == 'if': - ifs.append(ast.ListCompIf(tokens[index+1])) - index += 2 + while index < len(tokens): + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + if token.get_value() == 'if': + ifs.append(ast.ListCompIf(tokens[index+1])) + index += 2 + else: + break list_fors.append(ast.ListCompFor(ass_node, iterable, ifs)) ifs = [] else: - raise ValueError('Unexpected token: %s' % tokens[index]) + assert False, 'Unexpected token: %s' % token + # + # Original implementation: + # + # if tokens[index].get_value() == 'for': + # index += 1 # skip 'for' + # ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) + # index += 2 # skip 'in' + # iterable = tokens[index] + # index += 1 + # while index < len(tokens) and tokens[index].get_value() == 'if': + # ifs.append(ast.ListCompIf(tokens[index+1])) + # index += 2 + # list_fors.append(ast.ListCompFor(ass_node, iterable, ifs)) + # ifs = [] + # else: + # raise ValueError('Unexpected token: %s' % tokens[index]) return list_fors @@ -221,19 +313,26 @@ ifs = [] index = 0 while index < len(tokens): - if tokens[index].value == 'for': + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + check + if token.get_value() == 'for': index += 1 # skip 'for' ass_node = to_lvalue(tokens[index], consts.OP_ASSIGN) index += 2 # skip 'in' iterable = tokens[index] index += 1 - while index < len(tokens) and tokens[index].value == 'if': - ifs.append(ast.GenExprIf(tokens[index+1])) - index += 2 + while index < len(tokens): + token = tokens[index] + assert isinstance(token, TokenObject) # rtyper info + if token.get_value() == 'if': + ifs.append(ast.GenExprIf(tokens[index+1])) + index += 2 + else: + break genexpr_fors.append(ast.GenExprFor(ass_node, iterable, ifs)) ifs = [] else: - raise ValueError('Unexpected token: %s' % tokens[index]) + assert False, 'Unexpected token: %s' % token return genexpr_fors @@ -265,18 +364,23 @@ return ast.AssName( ast_node.name, flags ) elif isinstance(ast_node, ast.Tuple): nodes = [] - for node in ast_node.getChildren(): + # FIXME: should ast_node.getChildren() but it's not annotable + # because of flatten() + for node in ast_node.nodes: nodes.append(to_lvalue(node, flags)) # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssTuple(nodes) elif isinstance(ast_node, ast.List): nodes = [] - for node in ast_node.getChildren(): + # FIXME: should ast_node.getChildren() but it's not annotable + # because of flatten() + for node in ast_node.nodes: nodes.append(to_lvalue(node, flags)) # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssList(nodes) elif isinstance(ast_node, ast.Getattr): expr = ast_node.expr + assert isinstance(ast_node, ast.Getattr) attrname = ast_node.attrname return ast.AssAttr(expr, attrname, flags) elif isinstance(ast_node, ast.Subscript): @@ -310,20 +414,56 @@ return atoms def eval_number(value): - """temporary implementation""" - return eval(value) + """temporary implementation + eval_number intends to replace number = eval(value) ; return number + """ + from pypy.objspace.std.strutil import string_to_int, string_to_float + from pypy.objspace.std.strutil import ParseStringError + if value.endswith('l') or value.endswith('L'): + value = value[:-1] + try: + return string_to_int(value) + except ParseStringError: + return string_to_float(value) def eval_string(value): - """temporary implementation""" - return eval(value) + """temporary implementation + FIXME: need to be finished (check compile.c (parsestr) and + stringobject.c (PyString_DecodeEscape()) for complete implementation) + """ + # return eval(value) + assert isinstance(value, str) + if len(value) == 2: + return '' + result = '' + length = len(value) + quotetype = value[0] + index = 1 + while index < length and value[index] == quotetype: + index += 1 + if index == 6: + # empty strings like """""" or '''''' + return '' + # XXX: is it RPYTHON to do this value[index:-index] + chars = [char for char in value[index:len(value)-index]] +## for index in range(index, len(value)-index): +## result += value[index] + result = ''.join(chars) + result = result.replace('\\\\', '\\') + d = {'\\b' : '\b', '\\f' : '\f', '\\t' : '\t', '\\n' : '\n', + '\\r' : '\r', '\\v' : '\v', '\\a' : '\a', + } + for escaped, value in d.items(): + result = result.replace(escaped, value) + return result ## misc utilities, especially for power: rule def reduce_callfunc(obj, arglist): """generic factory for CallFunc nodes""" assert isinstance(arglist, ArglistObject) - arguments, stararg, dstararg = arglist.value - return ast.CallFunc(obj, arguments, stararg, dstararg) + return ast.CallFunc(obj, arglist.arguments, + arglist.stararg, arglist.dstararg) def reduce_subscript(obj, subscript): """generic factory for Subscript nodes""" @@ -348,7 +488,7 @@ token = tokens[0] # XXX HACK for when parse_attraccess is called from build_decorator if isinstance(token, TokenObject): - result = ast.Name(token.value) + result = ast.Name(token.get_value()) else: result = token index = 1 @@ -358,7 +498,7 @@ index += 1 token = tokens[index] assert isinstance(token, TokenObject) - result = ast.Getattr(result, token.value) + result = ast.Getattr(result, token.get_value()) elif isinstance(token, ArglistObject): result = reduce_callfunc(result, token) elif isinstance(token, SubscriptObject): @@ -402,14 +542,15 @@ atoms = get_atoms( builder, nb ) top = atoms[0] if isinstance(top, TokenObject): + # assert isinstance(top, TokenObject) # rtyper if top.name == tok.LPAR: if len(atoms) == 2: - builder.push(ast.Tuple([], top.line)) + builder.push(ast.Tuple([])) # , top.line)) else: builder.push( atoms[1] ) elif top.name == tok.LSQB: if len(atoms) == 2: - builder.push(ast.List([], top.line)) + builder.push(ast.List([])) # , top.line)) else: list_node = atoms[1] # XXX lineno is not on *every* child class of ast.Node @@ -423,16 +564,17 @@ # a : b , c : d # ^ +1 +2 +3 +4 items.append((atoms[index], atoms[index+2])) - builder.push(ast.Dict(items, top.line)) + builder.push(ast.Dict(items)) # top.line)) elif top.name == tok.NAME: - builder.push( ast.Name(top.value) ) + builder.push( ast.Name(top.get_value()) ) elif top.name == tok.NUMBER: - builder.push( ast.Const(eval_number(top.value)) ) + builder.push( ast.Const(eval_number(top.get_value())) ) elif top.name == tok.STRING: # need to concatenate strings in atoms s = '' for token in atoms: - s += eval_string(token.value) + assert isinstance(token, TokenObject) + s += eval_string(token.get_value()) builder.push( ast.Const(s) ) # assert False, "TODO (String)" elif top.name == tok.BACKQUOTE: @@ -550,8 +692,10 @@ ops = [] for i in range(1, l, 2): # if tok.name isn't in rpunct, then it should be - # 'is', 'is not', 'not' or 'not in' => tok.value - op_name = tok.tok_rpunct.get(atoms[i].name, atoms[i].value) + # 'is', 'is not', 'not' or 'not in' => tok.get_value() + token = atoms[i] + assert isinstance(token, TokenObject) + op_name = tok.tok_rpunct.get(token.name, token.get_value()) ops.append((op_name, atoms[i+1])) builder.push(ast.Compare(atoms[0], ops)) @@ -575,7 +719,9 @@ builder.push(atoms[0]) # l==2 means 'not in' or 'is not' elif l == 2: - if atoms[0].value == 'not': + token = atoms[0] + assert isinstance(token, TokenObject) + if token.get_value() == 'not': builder.push(TokenObject(tok.NAME, 'not in', None)) else: builder.push(TokenObject(tok.NAME, 'is not', None)) @@ -600,11 +746,11 @@ def build_testlist( builder, nb ): return build_binary_expr( builder, nb, ast.Tuple ) -def build_expr_stmt( builder, nb ): - atoms = get_atoms( builder, nb ) +def build_expr_stmt(builder, nb): + atoms = get_atoms(builder, nb) l = len(atoms) if l==1: - builder.push( ast.Discard( atoms[0] ) ) + builder.push(ast.Discard(atoms[0])) return op = atoms[1] if op.name == tok.EQUAL: @@ -618,8 +764,9 @@ else: assert l==3 lvalue = atoms[0] - assert is_augassign( lvalue ) - builder.push( ast.AugAssign( lvalue, op.get_name(), atoms[2] ) ) + # assert is_augassign( lvalue ) + assert isinstance(op, TokenObject) + builder.push(ast.AugAssign(lvalue, op.get_name(), atoms[2])) def return_one( builder, nb ): atoms = get_atoms( builder, nb ) @@ -713,7 +860,7 @@ # Case 1 : '(' ... if atoms[0].name == tok.LPAR: if len(atoms) == 2: # and atoms[1].token == tok.RPAR: - builder.push(ArglistObject('arglist', ([], None, None), None)) + builder.push(ArglistObject([], None, None)) elif len(atoms) == 3: # '(' Arglist ')' # push arglist on the stack builder.push(atoms[1]) @@ -736,7 +883,8 @@ def build_arglist(builder, nb): atoms = get_atoms(builder, nb) - builder.push(ArglistObject('arglist', parse_argument(atoms), None)) + arguments, stararg, dstararg = parse_argument(atoms) + builder.push(ArglistObject(arguments, stararg, dstararg)) def build_subscript(builder, nb): """'.' '.' '.' | [test] ':' [test] [':' [test]] | test""" @@ -788,25 +936,27 @@ def build_listmaker(builder, nb): """listmaker: test ( list_for | (',' test)* [','] )""" atoms = get_atoms(builder, nb) - if len(atoms) >= 2 and isinstance(atoms[1], TokenObject) and atoms[1].value == 'for': - # list comp - expr = atoms[0] - list_for = parse_listcomp(atoms[1:]) - builder.push(ast.ListComp(expr, list_for)) - else: - # regular list building (like in [1, 2, 3,]) - index = 0 - nodes = [] - while index < len(atoms): - nodes.append(atoms[index]) - index += 2 # skip comas - builder.push(ast.List(nodes)) + if len(atoms) >= 2 and isinstance(atoms[1], TokenObject): + token = atoms[1] + assert isinstance(token, TokenObject) # rtyper info + if token.get_value() == 'for': + # list comp + expr = atoms[0] + list_for = parse_listcomp(atoms[1:]) + builder.push(ast.ListComp(expr, list_for)) + return + # regular list building (like in [1, 2, 3,]) + index = 0 + nodes = [] + while index < len(atoms): + nodes.append(atoms[index]) + index += 2 # skip comas + builder.push(ast.List(nodes)) def build_decorator(builder, nb): """decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE""" atoms = get_atoms(builder, nb) - print "***** decorator", atoms nodes = [] # remove '@', '(' and ')' from atoms and use parse_attraccess for token in atoms[1:]: @@ -826,7 +976,16 @@ index = 0 decorators = [] decorator_node = None - while not (isinstance(atoms[index], TokenObject) and atoms[index].value == 'def'): + # the original loop was: + # while not (isinstance(atoms[index], TokenObject) and atoms[index].get_value() == 'def'): + # decorators.append(atoms[index]) + # index += 1 + while index < len(atoms): + atom = atoms[index] + if isinstance(atom, TokenObject): + assert isinstance(atom, TokenObject) # rtyper info + if atom.get_value() == 'def': + break decorators.append(atoms[index]) index += 1 if decorators: @@ -841,7 +1000,9 @@ # index += 1 # arglist.pop() # remove ':' names, default, flags = parse_arglist(arglist) - funcname = atoms[1].value + funcname_token = atoms[1] + assert isinstance(funcname_token, TokenObject) + funcname = funcname_token.get_value() arglist = atoms[2] code = atoms[-1] doc = get_docstring(code) @@ -853,12 +1014,14 @@ """classdef: 'class' NAME ['(' testlist ')'] ':' suite""" atoms = get_atoms(builder, nb) l = len(atoms) - # FIXME: docstring - classname = atoms[1].value + classname_token = atoms[1] + assert isinstance(classname_token, TokenObject) + classname = classname_token.get_value() if l == 4: basenames = [] body = atoms[3] - elif l == 7: + else: + assert l == 7 basenames = [] body = atoms[6] base = atoms[3] @@ -902,10 +1065,10 @@ while index < len(atoms): cur_token = atoms[index] assert isinstance(cur_token, TokenObject) # rtyper - if cur_token.value == 'elif': + if cur_token.get_value() == 'elif': tests.append((atoms[index+1], atoms[index+3])) index += 4 - else: # cur_token.value == 'else' + else: # cur_token.get_value() == 'else' else_ = atoms[index+2] break # break is not necessary builder.push(ast.If(tests, else_)) @@ -955,7 +1118,9 @@ atoms = get_atoms(builder, nb) names = [] for index in range(0, len(atoms), 2): - names.append(atoms[index].value) + token = atoms[index] + assert isinstance(token, TokenObject) + names.append(token.get_value()) builder.push(FPListObject('fplist', tuple(names), None)) @@ -996,9 +1161,14 @@ incr, name = parse_dotted_names(atoms[index:]) index += incr # 'as' value - if index < l and atoms[index].value == 'as': - as_name = atoms[index+1].value - index += 2 + if index < l: + token = atoms[index] + assert isinstance(token, TokenObject) + if token.get_value() == 'as': + token = atoms[index+1] + assert isinstance(token, TokenObject) + as_name = token.get_value() + index += 2 names.append((name, as_name)) # move forward until next ',' while index < l and atoms[index].name != tok.COMMA: @@ -1030,12 +1200,18 @@ l = len(tokens) names = [] while index < l: - name = tokens[index].value + token = tokens[index] + assert isinstance(token, TokenObject) + name = token.get_value() as_name = None index += 1 if index < l: - if tokens[index].value == 'as': - as_name = tokens[index+1].value + token = tokens[index] + assert isinstance(token, TokenObject) + if token.get_value() == 'as': + token = tokens[index+1] + assert isinstance(token, TokenObject) + as_name = token.get_value() index += 2 names.append((name, as_name)) if index < l: # case ',' @@ -1106,7 +1282,7 @@ for index in range(1, len(atoms), 2): token = atoms[index] assert isinstance(token, TokenObject) - names.append(token.value) + names.append(token.get_value()) builder.push(ast.Global(names)) @@ -1140,18 +1316,23 @@ body = atoms[2] token = atoms[3] assert isinstance(token, TokenObject) - if token.value == 'finally': + if token.get_value() == 'finally': builder.push(ast.TryFinally(body, atoms[5])) - else: # token.value == 'except' + else: # token.get_value() == 'except' index = 3 - while index < l and atoms[index].value == 'except': + token = atoms[index] + while isinstance(token, TokenObject) and token.get_value() == 'except': tokens_read, expr1, expr2, except_body = parse_except_clause(atoms[index:]) handlers.append((expr1, expr2, except_body)) index += tokens_read + if index < l: + token = atoms[index] + else: + break if index < l: token = atoms[index] assert isinstance(token, TokenObject) - assert token.value == 'else' + assert token.get_value() == 'else' else_ = atoms[index+2] # skip ':' builder.push(ast.TryExcept(body, handlers, else_)) @@ -1247,7 +1428,15 @@ def get_name(self): return tok.tok_rpunct.get(self.name, tok.tok_name.get(self.name, str(self.name))) - + + def get_value(self): + if self.value is None: + value = '' + else: + value = self.value + assert isinstance(value, str) + return value + def __str__(self): return "" % (self.get_name(), self.value) @@ -1289,6 +1478,12 @@ self.value is the 3-tuple (names, defaults, flags) """ + def __init__(self, arguments, stararg, dstararg): + self.name = 'arglist' + self.arguments = arguments + self.stararg = stararg + self.dstararg = dstararg + def __str__(self): return "" % self.value @@ -1329,16 +1524,16 @@ class AstBuilder(BaseGrammarBuilder): """A builder that directly produce the AST""" - def __init__( self, rules=None, debug=0 ): - BaseGrammarBuilder.__init__(self, rules, debug ) + def __init__(self, rules=None, debug=0): + BaseGrammarBuilder.__init__(self, rules, debug) self.rule_stack = [] def context(self): return AstBuilderContext(self.rule_stack) def restore(self, ctx): - if DEBUG_MODE: - print "Restoring context (%s)" % (len(ctx.rule_stack)) +## if DEBUG_MODE: +## print "Restoring context (%s)" % (len(ctx.rule_stack)) assert isinstance(ctx, AstBuilderContext) self.rule_stack = ctx.rule_stack @@ -1348,11 +1543,13 @@ def push(self, obj): self.rule_stack.append( obj ) if not isinstance(obj, RuleObject) and not isinstance(obj, TokenObject): - if DEBUG_MODE: - print "Pushed:", str(obj), len(self.rule_stack) +## if DEBUG_MODE: +## print "Pushed:", str(obj), len(self.rule_stack) + pass elif isinstance(obj, TempRuleObject): - if DEBUG_MODE: - print "Pushed:", str(obj), len(self.rule_stack) +## if DEBUG_MODE: +## print "Pushed:", str(obj), len(self.rule_stack) + pass # print "\t", self.rule_stack def push_tok(self, name, value, src ): @@ -1365,53 +1562,53 @@ # Do nothing, keep rule on top of the stack rule_stack = self.rule_stack[:] if rule.is_root(): - if DEBUG_MODE: - print "ALT:", sym.sym_name[rule.codename], self.rule_stack +## if DEBUG_MODE: +## print "ALT:", sym.sym_name[rule.codename], self.rule_stack builder_func = ASTRULES.get(rule.codename, None) if builder_func: builder_func(self, 1) else: - if DEBUG_MODE: - print "No reducing implementation for %s, just push it on stack" % ( - sym.sym_name[rule.codename]) +## if DEBUG_MODE: +## print "No reducing implementation for %s, just push it on stack" % ( +## sym.sym_name[rule.codename]) self.push_rule(rule.codename, 1, source) else: self.push_rule(rule.codename, 1, source) - if DEBUG_MODE > 1: - show_stack(rule_stack, self.rule_stack) - x = raw_input("Continue ?") +## if DEBUG_MODE > 1: +## show_stack(rule_stack, self.rule_stack) +## x = raw_input("Continue ?") return True def sequence(self, rule, source, elts_number): """ """ rule_stack = self.rule_stack[:] if rule.is_root(): - if DEBUG_MODE: - print "SEQ:", sym.sym_name[rule.codename] - builder_func = ASTRULES.get(rule.codename) +## if DEBUG_MODE: +## print "SEQ:", sym.sym_name[rule.codename] + builder_func = ASTRULES.get(rule.codename, None) if builder_func: # print "REDUCING SEQUENCE %s" % sym.sym_name[rule.codename] builder_func(self, elts_number) else: - if DEBUG_MODE: - print "No reducing implementation for %s, just push it on stack" % ( - sym.sym_name[rule.codename]) +## if DEBUG_MODE: +## print "No reducing implementation for %s, just push it on stack" % ( +## sym.sym_name[rule.codename]) self.push_rule(rule.codename, elts_number, source) else: self.push_rule(rule.codename, elts_number, source) - if DEBUG_MODE > 1: - show_stack(rule_stack, self.rule_stack) - raw_input("Continue ?") +## if DEBUG_MODE > 1: +## show_stack(rule_stack, self.rule_stack) +## raw_input("Continue ?") return True def token(self, name, value, source): - if DEBUG_MODE: - print "TOK:", tok.tok_name[name], name, value +## if DEBUG_MODE: +## print "TOK:", tok.tok_name[name], name, value self.push_tok(name, value, source) return True def show_stack(before, after): - """debuggin helper function""" + """debugging helper function""" size1 = len(before) size2 = len(after) for i in range(max(size1, size2)): Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Fri Aug 12 18:11:48 2005 @@ -4,6 +4,7 @@ import pythonparse from tuplebuilder import TupleBuilder +from astbuilder import AstBuilder from pypy.interpreter.pyparser.error import ParseError from pypy.interpreter.pyparser import pysymbol @@ -100,6 +101,12 @@ ast = transformer.compile_node(tuples) return ast +def ast_from_input_(input, mode): + builder = AstBuilder() + target = TARGET_DICT[mode] + PYTHON_PARSER.parse_source(input, target, builder) + return builder.rule_stack[-1] + ## TARGET FOR ANNOTATORS ############################################# def annotateme(source): """This function has no other role than testing the parser's annotation Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Fri Aug 12 18:11:48 2005 @@ -421,7 +421,9 @@ 'snippet_2.py', 'snippet_3.py', 'snippet_4.py', - 'snippet_comment.py', + # XXX: skip snippet_comment because we don't have a replacement of + # eval for numbers and strings (eval_number('0x1L') fails) + # 'snippet_comment.py', 'snippet_encoding_declaration2.py', 'snippet_encoding_declaration3.py', 'snippet_encoding_declaration.py', @@ -460,3 +462,13 @@ print "TESTING", filepath source = file(filepath).read() yield check_expression, source, 'exec' + + +def test_eval_string(): + from pypy.interpreter.pyparser.astbuilder import eval_string + test = ['""', "''", '""""""', "''''''", "''' '''", '""" """', '"foo"', + "'foo'", '"""\n"""', '"\\ "', '"\\n"', + # '"\""', + ] + for data in test: + assert eval_string(data) == eval(data) From adim at codespeak.net Fri Aug 12 18:53:06 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Fri, 12 Aug 2005 18:53:06 +0200 (CEST) Subject: [pypy-svn] r16014 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050812165306.3DD5027B64@code1.codespeak.net> Author: adim Date: Fri Aug 12 18:53:04 2005 New Revision: 16014 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py Log: removed unneeded asserts Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Fri Aug 12 18:53:04 2005 @@ -46,7 +46,6 @@ first = tokens[0] assert isinstance(first, TokenObject) name = first.get_value() - assert isinstance(name, str) l = len(tokens) index = 1 for index in range(1, l, 2): @@ -190,8 +189,8 @@ assert len(stack) == 1, "At the end of parse_fpdef, len(stack) should be 1, got %s" % stack return tokens_read, tuple(stack[0]) -# parse_fpdef = rpython_parse_fpdef -parse_fpdef = working_parse_fpdef +parse_fpdef = rpython_parse_fpdef +# parse_fpdef = working_parse_fpdef def parse_arglist(tokens): """returns names, defaults, flags""" @@ -433,7 +432,6 @@ stringobject.c (PyString_DecodeEscape()) for complete implementation) """ # return eval(value) - assert isinstance(value, str) if len(value) == 2: return '' result = '' @@ -1434,7 +1432,7 @@ value = '' else: value = self.value - assert isinstance(value, str) + # assert isinstance(value, str) return value def __str__(self): From adim at codespeak.net Fri Aug 12 18:56:32 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Fri, 12 Aug 2005 18:56:32 +0200 (CEST) Subject: [pypy-svn] r16015 - pypy/dist/pypy/translator/goal Message-ID: <20050812165632.86F7A27B64@code1.codespeak.net> Author: adim Date: Fri Aug 12 18:56:31 2005 New Revision: 16015 Modified: pypy/dist/pypy/translator/goal/targetparser.py Log: the new parser's target use astbuilder instead of tuplebuilder Modified: pypy/dist/pypy/translator/goal/targetparser.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetparser.py (original) +++ pypy/dist/pypy/translator/goal/targetparser.py Fri Aug 12 18:56:31 2005 @@ -8,13 +8,16 @@ this_dir = os.path.dirname(sys.argv[0]) -from pypy.interpreter.pyparser.pythonutil import annotateme +# from pypy.interpreter.pyparser.pythonutil import annotateme # __________ Entry point __________ -entry_point = annotateme +# entry_point = annotateme + +from pypy.interpreter.pyparser.pythonutil import ast_from_input_ +entry_point = ast_from_input_ # _____ Define and setup target ___ def target(): - return entry_point, [str] + return entry_point, [str, str] # _____ Run translated _____ def run(c_entry_point): From tismer at codespeak.net Fri Aug 12 19:26:15 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 12 Aug 2005 19:26:15 +0200 (CEST) Subject: [pypy-svn] r16016 - pypy/dist/pypy/objspace/std Message-ID: <20050812172615.8AE6B27B64@code1.codespeak.net> Author: tismer Date: Fri Aug 12 19:26:13 2005 New Revision: 16016 Modified: pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/intobject.py pypy/dist/pypy/objspace/std/longobject.py pypy/dist/pypy/objspace/std/model.py Log: a little clean-up to int/long/floatobject: Use multimethod exceptions instead of directly calling surrogate functions. Reason: I would like to have the objspace implementations create exactly the type they are made for, or raise NonImplemented. That makes it easier to call such functions from somewhere else. Although I also think that calling into objspace implementations is just a temporary thing, and we should have an extra sub-interface for everything that gets called "under the hood" and refrain from calling into W_Anything if it is avoidable. I will employ this stylepretty soon, isolating the long impl from the objspace and putting it into,say, longutil for the moment. Btw., the way pow() needs to be redirected is slightly inefficient, and using the NotImplementedto resolve it is slightly an abuse, because the reason why we cannot early dispatch on it is that we are lacking an ability to express an interface with non-negative ints. Would it be possible to do that? Like pow__Int_Unsigned_None ??? Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Fri Aug 12 19:26:13 2005 @@ -1,6 +1,7 @@ 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, _AsDouble, _FromDouble from pypy.rpython.rarithmetic import ovfcheck_float_to_int, intmask ############################################################## @@ -38,6 +39,14 @@ def delegate_Int2Float(w_intobj): return W_FloatObject(w_intobj.space, float(w_intobj.intval)) +# long-to-float delegation +def delegate_Long2Float(w_longobj): + try: + return W_FloatObject(w_longobj.space, _AsDouble(w_longobj)) + except OverflowError: + raise OperationError(w_longobj.space.w_OverflowError, + w_longobj.space.wrap("long int too large to convert to float")) + # float__Float is supposed to do nothing, unless it has # a derived float object, where it should return @@ -56,6 +65,13 @@ else: return space.newint(value) +def long__Float(space, w_floatobj): + try: + return _FromDouble(space, w_floatobj.floatval) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("cannot convert float infinity to long")) + def float_w__Float(space, w_float): return w_float.floatval @@ -308,6 +324,7 @@ return W_FloatObject(space, z) + def neg__Float(space, w_float1): return W_FloatObject(space, -w_float1.floatval) @@ -335,3 +352,18 @@ return space.newtuple([W_FloatObject(space, w_float.floatval)]) register_all(vars()) + +# pow delegation for negative 1st arg +def pow_neg__Long_Long_None(space, w_int1, w_int2, thirdarg): + w_float1 = delegate_Long2Float(w_int1) + w_float2 = delegate_Long2Float(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) + +def pow_neg__Int_Int_None(space, w_int1, w_int2, thirdarg): + w_float1 = delegate_Int2Float(w_int1) + w_float2 = delegate_Int2Float(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) Modified: pypy/dist/pypy/objspace/std/intobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/intobject.py (original) +++ pypy/dist/pypy/objspace/std/intobject.py Fri Aug 12 19:26:13 2005 @@ -202,9 +202,6 @@ raise OperationError(space.w_TypeError, space.wrap("pow() 2nd argument " "cannot be negative when 3rd argument specified")) - return space.pow(space.float(space.wrap(iv)), - space.float(space.wrap(iw)), - space.w_None) ## bounce it, since it always returns float raise FailedToImplement(space.w_ValueError, space.wrap("integer exponentiation")) @@ -229,15 +226,6 @@ space.wrap("integer exponentiation")) return W_IntObject(space, ix) -""" -def pow__Int_Int_Int(space, w_int1, w_int2, w_int3): - x = w_int1.intval - y = w_int2.intval - z = w_int3.intval - ret = _impl_int_int_pow(space, x, y, z) - return W_IntObject(space, ret) -""" - def pow__Int_Int_Int(space, w_int1, w_int2, w_int3): x = w_int1.intval y = w_int2.intval Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Fri Aug 12 19:26:13 2005 @@ -1,7 +1,6 @@ import sys, operator from pypy.objspace.std.objspace import * from pypy.objspace.std.intobject import W_IntObject -from pypy.objspace.std.floatobject import W_FloatObject from pypy.objspace.std.noneobject import W_NoneObject from pypy.rpython.rarithmetic import LONG_BIT, LONG_MASK, intmask, r_uint @@ -93,6 +92,7 @@ # digits, sign = args_from_long(digits) w_self.digits = DigitArray(digits) w_self.sign = sign + w_self.space = space assert len(w_self.digits) def fromint(space, intval): @@ -175,14 +175,6 @@ def delegate_Int2Long(w_intobj): return long__Int(w_intobj.space, w_intobj) -# long-to-float delegation -def delegate_Long2Float(w_longobj): - try: - return W_FloatObject(w_longobj.space, _AsDouble(w_longobj)) - except OverflowError: - raise OperationError(w_longobj.space.w_OverflowError, - w_longobj.space.wrap("long int too large to convert to float")) - # long__Long is supposed to do nothing, unless it has # a derived long object, where it should return @@ -212,13 +204,6 @@ raise OperationError(space.w_OverflowError, space.wrap("long int too large to convert to float")) -def long__Float(space, w_floatobj): - try: - return _FromDouble(space, w_floatobj.floatval) - except OverflowError: - raise OperationError(space.w_OverflowError, - space.wrap("cannot convert float infinity to long")) - def int_w__Long(space, w_value): try: return _AsLong(w_value) @@ -374,9 +359,8 @@ raise OperationError(space.w_TypeError, space.wrap( "pow() 2nd argument " "cannot be negative when 3rd argument specified")) - return space.pow(space.newfloat(_AsDouble(a)), - space.newfloat(_AsDouble(b)), - space.w_None) + raise FailedToImplement(space.w_ValueError, space.wrap( + "long pow() to negative")) if c is not None: # if modulus == 0: @@ -1642,7 +1626,7 @@ elif s[p] == '+': p += 1 - a = W_LongObject(space, [0], 1) + a = W_LongObject.fromint(space, 0) cnt = DEC_PER_DIGIT tens = 1 dig = 0 @@ -1670,3 +1654,6 @@ digit >>= 1 bits += 1 return bits + +def _get_odd(a): + return a.digits[0] & 1 Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Fri Aug 12 19:26:13 2005 @@ -99,7 +99,7 @@ (floatobject.W_FloatObject, floatobject.delegate_Int2Float), ] self.typeorder[longobject.W_LongObject] += [ - (floatobject.W_FloatObject, longobject.delegate_Long2Float), + (floatobject.W_FloatObject, floatobject.delegate_Long2Float), ] self.typeorder[stringobject.W_StringObject] += [ (unicodeobject.W_UnicodeObject, unicodeobject.delegate_String2Unicode), From tismer at codespeak.net Fri Aug 12 19:59:00 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 12 Aug 2005 19:59:00 +0200 (CEST) Subject: [pypy-svn] r16017 - pypy/dist/pypy/objspace/std Message-ID: <20050812175900.E76DB27B64@code1.codespeak.net> Author: tismer Date: Fri Aug 12 19:58:59 2005 New Revision: 16017 Modified: pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/longobject.py Log: corrected a false comment of mine in floatobject.py. added some commentary for the tiny _get_odd() function in longobject.py, which is a bit special because it is the only case where you can use the lowest bit without taking the sign bit into account. A general get_bit(a,n) operation would be to expensive to be worth it, unless we explicitly say it ignores the sign. Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Fri Aug 12 19:58:59 2005 @@ -353,7 +353,7 @@ register_all(vars()) -# pow delegation for negative 1st arg +# pow delegation for negative 2nd arg def pow_neg__Long_Long_None(space, w_int1, w_int2, thirdarg): w_float1 = delegate_Long2Float(w_int1) w_float2 = delegate_Long2Float(w_int2) Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Fri Aug 12 19:58:59 2005 @@ -1656,4 +1656,9 @@ return bits def _get_odd(a): + # Note: this is a tiny optimization. + # Instead of implementing a general "get_bit" operation, + # which would be expensive for negative numbers, + # get_odd has the nice feature that it is always correct, + # no matter what the sign is (two's complement) return a.digits[0] & 1 From cfbolz at codespeak.net Fri Aug 12 20:32:54 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 12 Aug 2005 20:32:54 +0200 (CEST) Subject: [pypy-svn] r16018 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050812183254.87ECD27B64@code1.codespeak.net> Author: cfbolz Date: Fri Aug 12 20:32:53 2005 New Revision: 16018 Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py Log: disabling failing test for now. Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 12 20:32:53 2005 @@ -7,6 +7,10 @@ from pypy.rpython.memory import gclltype from pypy.rpython.memory.test.test_llinterpsim import interpret +def setup_module(mod): + mod.logstate = py.log._getstate() + py.log.setconsumer("llinterp", py.log.STDOUT) + py.log.setconsumer("llinterp operation", None ) def test_free_non_gc_object(): class TestClass(object): @@ -109,7 +113,7 @@ assert simulator.current_size - curr < 16000 print "size before: %s, size after %s" % (curr, simulator.current_size) - def test_llinterp_tuples(self): + def DONOTtest_llinterp_tuples(self): from pypy.rpython.memory.lladdress import simulator gclltype.create_gc = gclltype.create_mark_sweep_gc curr = simulator.current_size From tismer at codespeak.net Fri Aug 12 20:33:03 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 12 Aug 2005 20:33:03 +0200 (CEST) Subject: [pypy-svn] r16019 - pypy/dist/pypy/objspace/std Message-ID: <20050812183303.2FBA827B6D@code1.codespeak.net> Author: tismer Date: Fri Aug 12 20:33:01 2005 New Revision: 16019 Modified: pypy/dist/pypy/objspace/std/floattype.py pypy/dist/pypy/objspace/std/strutil.py Log: reimplementation of string_to_float at interp level. Changed floattype to use this. This is intermediate, interp_string_to_float will get the old (spaceless) interface back after factoring the long implementation out of longobject. Modified: pypy/dist/pypy/objspace/std/floattype.py ============================================================================== --- pypy/dist/pypy/objspace/std/floattype.py (original) +++ pypy/dist/pypy/objspace/std/floattype.py Fri Aug 12 20:33:01 2005 @@ -1,6 +1,9 @@ from pypy.objspace.std.stdtypedef import * from pypy.interpreter.error import OperationError from pypy.objspace.std.strutil import string_to_float, ParseStringError +from pypy.objspace.std.strutil import interp_string_to_float + +USE_NEW_S2F = True def descr__new__(space, w_floattype, w_x=0.0): from pypy.objspace.std.floatobject import W_FloatObject @@ -8,19 +11,21 @@ if space.is_true(space.isinstance(w_value, space.w_str)): strvalue = space.str_w(w_value) try: - value = string_to_float(strvalue) + if USE_NEW_S2F: + value = interp_string_to_float(space, strvalue) + else: + value = string_to_float(strvalue) except ParseStringError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) - except OverflowError, e: - # this should not happen, but if it does, catch it! - raise OperationError(space.w_OverflowError, - space.wrap(str(e))) elif space.is_true(space.isinstance(w_value, space.w_unicode)): from unicodeobject import unicode_to_decimal_w strvalue = unicode_to_decimal_w(space, w_value) try: - value = string_to_float(strvalue) + if USE_NEW_S2F: + value = interp_string_to_float(space, strvalue) + else: + value = string_to_float(strvalue) except ParseStringError, e: raise OperationError(space.w_ValueError, space.wrap(e.msg)) Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Fri Aug 12 20:33:01 2005 @@ -3,7 +3,7 @@ """ from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_float_to_int, parts_to_float - +from pypy.interpreter.error import OperationError import math # XXX factor more functions out of stringobject.py. @@ -293,14 +293,14 @@ # 1) parse the string into pieces. sign, before_point, after_point, exponent = break_up_float(s) - if not before_point and not after_point: + digits = before_point + after_point + if digits: raise ParseStringError("invalid literal for float()") # 2) pre-calculate digit exponent dexp. dexp = len(before_point) # 3) truncate and adjust dexp. - digits = before_point + after_point p = 0 plim = dexp + len(after_point) while p < plim and digits[p] == '0': @@ -362,3 +362,124 @@ r = -r return r + + +# the "real" implementation. +# for comments, see above. +# XXX probably this very specific thing should go into longobject? + +def interp_string_to_float(space, s): + """ + Conversion of string to float. + This version tries to only raise on invalid literals. + Overflows should be converted to infinity whenever possible. + + Expects an unwrapped string and return an unwrapped float. + """ + + if not s: + raise OperationError(space.w_ValueError, space.wrap( + "empty string for float()")) + + # 1) parse the string into pieces. + sign, before_point, after_point, exponent = break_up_float(s) + + digits = before_point + after_point + if not digits: + raise ParseStringError("invalid literal for float()") + + # 2) pre-calculate digit exponent dexp. + dexp = len(before_point) + + # 3) truncate and adjust dexp. + p = 0 + plim = dexp + len(after_point) + while p < plim and digits[p] == '0': + p += 1 + dexp -= 1 + digits = digits[p : p + MANTISSA_DIGITS] + p = len(digits) - 1 + while p >= 0 and digits[p] == '0': + p -= 1 + dexp -= p + 1 + p += 1 + assert p >= 0 + digits = digits[:p] + if len(digits) == 0: + digits = '0' + + # a few abbreviations + from pypy.objspace.std import longobject + mklong = longobject.W_LongObject.fromint + d2long = longobject._decimalstr_to_long + adlong = longobject.add__Long_Long + long2i = longobject._AsLong + double = longobject._AsDouble + longup = longobject._impl_long_long_pow + multip = longobject.mul__Long_Long + divide = longobject.div__Long_Long + bitlen = longobject._count_bits + lshift = longobject.lshift__Long_Long + rshift = longobject.rshift__Long_Long + getodd = longobject._get_odd + + # 4) compute the exponent and truncate to +-400 + if not exponent: + exponent = '0' + w_le = d2long(space, exponent) + w_le = adlong(space, w_le, mklong(space, dexp)) + try: + e = long2i(w_le) + except OverflowError: + e = w_le.sign * 400 + if e >= 400: + e = 400 + elif e <= -400: + e = -400 + + # 5) compute the value using long math and proper rounding. + w_lr = d2long(space, digits) + w_10 = mklong(space, 10) + w_1 = mklong(space, 1) + if e >= 0: + bits = 0 + w_pten = longup(space, w_10, mklong(space, e), None) + w_m = multip(space, w_lr, w_pten) + else: + # compute a sufficiently large scale + prec = MANTISSA_DIGITS * 2 + 22 # 128, maybe + bits = - (int(math.ceil(-e / math.log10(2) - 1e-10)) + prec) + w_scale = lshift(space, w_1, mklong(space, -bits)) + w_pten = longup(space, w_10, mklong(space, -e), None) + w_tmp = multip(space, w_lr, w_scale) + w_m = divide(space, w_tmp, w_pten) + + # we now have a fairly large mantissa. + # Shift it and round the last bit. + + # first estimate the bits and do a big shift + mbits = bitlen(w_m) + needed = MANTISSA_BITS + if mbits > needed: + if mbits > needed+1: + shifted = mbits - (needed+1) + w_m = rshift(space, w_m, mklong(space, shifted)) + bits += shifted + # do the rounding + bits += 1 + round = getodd(w_m) + w_m = rshift(space, w_m, w_1) + w_m = adlong(space, w_m, mklong(space, round)) + + try: + r = math.ldexp(double(w_m), bits) + # XXX I guess we do not check for overflow in ldexp as we agreed to! + if r == 2*r and r != 0.0: + raise OverflowError + except OverflowError: + r = 1e200 * 1e200 # produce inf, hopefully + + if sign == '-': + r = -r + + return r From cfbolz at codespeak.net Fri Aug 12 21:03:38 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 12 Aug 2005 21:03:38 +0200 (CEST) Subject: [pypy-svn] r16020 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050812190338.D097D27B64@code1.codespeak.net> Author: cfbolz Date: Fri Aug 12 21:03:38 2005 New Revision: 16020 Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/simulator.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: bug: gcwrapper sometimes allocated a block of zero bytes and freed it later (the simulator didn't check for that). The next block then had the same address and thus got freed as well :-( Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Fri Aug 12 21:03:38 2005 @@ -32,7 +32,10 @@ raw_free(self.pseudo_root_pointers) self.roots = self.llinterp.find_roots() print "found:", self.roots - self.pseudo_root_pointers = raw_malloc(len(self.roots) * INT_SIZE) + if len(self.roots) == 0: + self.pseudo_root_pointers = NULL + else: + self.pseudo_root_pointers = raw_malloc(len(self.roots) * INT_SIZE) ll = AddressLinkedList() for i, root in enumerate(self.roots): self.pseudo_root_pointers.address[i] = root._address Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Fri Aug 12 21:03:38 2005 @@ -113,6 +113,7 @@ return self.blocks[mid] def malloc(self, size): + assert size > 0 result = self.freememoryaddress self.blocks.append(MemoryBlock(result, size)) self.freememoryaddress += size Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 12 21:03:38 2005 @@ -10,7 +10,7 @@ def setup_module(mod): mod.logstate = py.log._getstate() py.log.setconsumer("llinterp", py.log.STDOUT) - py.log.setconsumer("llinterp operation", None ) + py.log.setconsumer("llinterp operation", None) def test_free_non_gc_object(): class TestClass(object): @@ -113,7 +113,7 @@ assert simulator.current_size - curr < 16000 print "size before: %s, size after %s" % (curr, simulator.current_size) - def DONOTtest_llinterp_tuples(self): + def test_llinterp_tuples(self): from pypy.rpython.memory.lladdress import simulator gclltype.create_gc = gclltype.create_mark_sweep_gc curr = simulator.current_size From cfbolz at codespeak.net Fri Aug 12 21:47:04 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 12 Aug 2005 21:47:04 +0200 (CEST) Subject: [pypy-svn] r16021 - in pypy/dist/pypy/rpython: . memory memory/test Message-ID: <20050812194704.32B4A27B64@code1.codespeak.net> Author: cfbolz Date: Fri Aug 12 21:47:03 2005 New Revision: 16021 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: changed convertllype so that the gc can also handle programs where globals contain root point Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Aug 12 21:47:03 2005 @@ -16,11 +16,9 @@ class LLInterpreter(object): """ low level interpreter working with concrete values. """ - def __init__(self, flowgraphs, typer, lltype=lltype, prepare_graphs=None): - if prepare_graphs is not None: - prepare_graphs(flowgraphs) - if hasattr(lltype, "create_gc"): - self.gc = lltype.create_gc(self) + def __init__(self, flowgraphs, typer, lltype=lltype): + if hasattr(lltype, "prepare_graphs_and_create_gc"): + self.gc = lltype.prepare_graphs_and_create_gc(self, flowgraphs) else: self.gc = None self.flowgraphs = flowgraphs Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Fri Aug 12 21:47:03 2005 @@ -15,10 +15,23 @@ FUNCTIONTYPES = (types.FunctionType, types.UnboundMethodType, types.BuiltinFunctionType) +INT_SIZE = struct.calcsize("i") + class LLTypeConverter(object): def __init__(self, address): + self.type_to_typeid = {} + self.types = [] self.converted = {} self.curraddress = address + self.constantroots = [] + + def get_typeid(self, TYPE): + if TYPE not in self.type_to_typeid: + index = len(self.types) + self.type_to_typeid[TYPE] = index + self.types.append(TYPE) + typeid = self.type_to_typeid[TYPE] + return typeid def convert(self, val_or_ptr, inline_to_addr=None, from_parent=False): TYPE = lltype.typeOf(val_or_ptr) @@ -53,11 +66,16 @@ startaddr = inline_to_addr else: startaddr = self.curraddress + startaddr.signed[0] = 0 + startaddr.signed[1] = self.get_typeid(TYPE) + startaddr += 2 * INT_SIZE + self.constantroots.append( + simulatorptr(lltype.Ptr(TYPE), startaddr)) + self.curraddress += size + 2 * INT_SIZE self.converted[_array] = startaddr startaddr.signed[0] = arraylength curraddr = startaddr + get_fixed_size(TYPE) varsize = get_variable_size(TYPE) - self.curraddress += size for item in _array.items: self.convert(item, curraddr, from_parent=True) curraddr += varsize @@ -84,8 +102,13 @@ startaddr = inline_to_addr else: startaddr = self.curraddress + startaddr.signed[0] = 0 + startaddr.signed[1] = self.get_typeid(TYPE) + startaddr += 2 * INT_SIZE + self.constantroots.append( + simulatorptr(lltype.Ptr(TYPE), startaddr)) + self.curraddress += size + 2 * INT_SIZE self.converted[_struct] = startaddr - self.curraddress += size for name in TYPE._flds: addr = startaddr + layout[name] self.convert(getattr(_struct, name), addr, from_parent=True) @@ -159,20 +182,25 @@ elif isinstance(cand, lltype._array): seen[cand] = True length = len(cand.items) - total_size += get_total_size(cand._TYPE, length) + total_size += get_total_size(cand._TYPE, length) * 2 * INT_SIZE for item in cand.items: candidates.append(item) elif isinstance(cand, lltype._struct): seen[cand] = True parent = cand._parentstructure() if parent is not None: + has_parent = True candidates.append(parent) - TYPE = cand._TYPE - if TYPE._arrayfld is not None: - total_size += get_total_size( - TYPE, len(getattr(cand, TYPE._arrayfld).items)) else: - total_size += get_total_size(TYPE) + has_parent = False + TYPE = cand._TYPE + if not has_parent: + if TYPE._arrayfld is not None: + total_size += get_total_size( + TYPE, len(getattr(cand, TYPE._arrayfld).items)) + else: + total_size += get_total_size(TYPE) + total_size += INT_SIZE * 2 for name in TYPE._flds: candidates.append(getattr(cand, name)) elif isinstance(cand, lltype._opaque): Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Fri Aug 12 21:47:03 2005 @@ -55,7 +55,9 @@ # roots is a list of addresses to addresses: objects.append(curr.address[0]) gc_info = curr.address[0] - 2 * INT_SIZE - assert gc_info.signed[0] == 0 + # constants roots are not malloced and thus don't have their mark + # bit reset + gc_info.signed[0] = 0 while 1: #mark curr = objects.pop() print "object: ", curr Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Fri Aug 12 21:47:03 2005 @@ -9,6 +9,7 @@ from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr from pypy.rpython.memory.lltypesimulation import pyobjectptr +from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter def notimplemented(*args, **kwargs): @@ -29,21 +30,21 @@ del notimplemented -def prepare_graphs(flowgraphs): - from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter +def create_no_gc(llinterp, flowgraphs): fgcc = FlowGraphConstantConverter(flowgraphs) - fgcc.convert() - -def create_no_gc(llinterp): + fgcc.convert() return None -def create_mark_sweep_gc(llinterp): +def create_mark_sweep_gc(llinterp, flowgraphs): from pypy.rpython.memory.gcwrapper import GcWrapper, LLInterpObjectModel from pypy.rpython.memory.gc import MarkSweepGC - om = LLInterpObjectModel(llinterp) + fgcc = FlowGraphConstantConverter(flowgraphs) + fgcc.convert() + om = LLInterpObjectModel(llinterp, fgcc.cvter.types, + fgcc.cvter.type_to_typeid, + fgcc.cvter.constantroots) gc = MarkSweepGC(om, 4096) wrapper = GcWrapper(llinterp, gc) return wrapper -create_gc = create_no_gc - +prepare_graphs_and_create_gc = create_mark_sweep_gc Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Fri Aug 12 21:47:03 2005 @@ -5,9 +5,10 @@ from pypy.rpython.memory.gc import MarkSweepGC class LLInterpObjectModel(object): - def __init__(self, llinterp): - self.type_to_typeid = {} - self.types = [] + def __init__(self, llinterp, types, type_to_typeid, constantroots): + self.types = types + self.type_to_typeid = type_to_typeid + self.constantroots = constantroots self.roots = [] self.pseudo_root_pointers = NULL self.llinterp = llinterp @@ -30,7 +31,7 @@ print "getting roots" if self.pseudo_root_pointers != NULL: raw_free(self.pseudo_root_pointers) - self.roots = self.llinterp.find_roots() + self.roots = self.llinterp.find_roots() + self.constantroots print "found:", self.roots if len(self.roots) == 0: self.pseudo_root_pointers = NULL Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 12 21:47:03 2005 @@ -6,11 +6,16 @@ from pypy.rpython.memory.simulator import MemorySimulatorError from pypy.rpython.memory import gclltype from pypy.rpython.memory.test.test_llinterpsim import interpret +from pypy.rpython.memory.lladdress import simulator def setup_module(mod): mod.logstate = py.log._getstate() py.log.setconsumer("llinterp", py.log.STDOUT) py.log.setconsumer("llinterp operation", None) + gclltype.prepare_graphs_and_create_gc = gclltype.create_mark_sweep_gc + +def teardown_module(mod): + gclltype.prepare_graphs_and_create_gc = gclltype.create_no_gc def test_free_non_gc_object(): class TestClass(object): @@ -97,8 +102,6 @@ py.test.raises(MemorySimulatorError, "addr2.signed[0]") def test_llinterp_lists(self): - from pypy.rpython.memory.lladdress import simulator - gclltype.create_gc = gclltype.create_mark_sweep_gc curr = simulator.current_size def malloc_a_lot(): i = 0 @@ -114,8 +117,6 @@ print "size before: %s, size after %s" % (curr, simulator.current_size) def test_llinterp_tuples(self): - from pypy.rpython.memory.lladdress import simulator - gclltype.create_gc = gclltype.create_mark_sweep_gc curr = simulator.current_size def malloc_a_lot(): i = 0 Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Fri Aug 12 21:47:03 2005 @@ -41,8 +41,7 @@ t, typer = gengraph(func, [annotation(x) for x in values], viewbefore, policy) - interp = LLInterpreter(t.flowgraphs, typer, gclltype, - gclltype.prepare_graphs) + interp = LLInterpreter(t.flowgraphs, typer, gclltype) _tcache[key] = (t, interp) # keep the cache small _lastinterpreted.append(key) From cfbolz at codespeak.net Fri Aug 12 21:59:27 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 12 Aug 2005 21:59:27 +0200 (CEST) Subject: [pypy-svn] r16022 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050812195927.9F60227B64@code1.codespeak.net> Author: cfbolz Date: Fri Aug 12 21:59:26 2005 New Revision: 16022 Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py Log: test for last checkin. The checkin message of the last checkin should have been: changed convertllype so that the gc can also handle programs where globals contain root pointers. Global constants now have two words for the GC reserved as well. Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 12 21:59:26 2005 @@ -131,3 +131,17 @@ res = interpret(malloc_a_lot, []) assert simulator.current_size - curr < 16000 print "size before: %s, size after %s" % (curr, simulator.current_size) + + def test_global_list(self): + curr = simulator.current_size + lst = [] + def append_to_list(i, j): + lst.append([i] * 500) + return lst[j][0] + res = interpret(append_to_list, [0, 0]) + assert res == 0 + for i in range(1, 15): + res = interpret(append_to_list, [i, i - 1]) + assert res == i - 1# crashes if constants are not considered roots + + From cfbolz at codespeak.net Fri Aug 12 22:07:32 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 12 Aug 2005 22:07:32 +0200 (CEST) Subject: [pypy-svn] r16023 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050812200732.2F54327B61@code1.codespeak.net> Author: cfbolz Date: Fri Aug 12 22:07:31 2005 New Revision: 16023 Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py Log: one more random tests that allocates memory Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 12 22:07:31 2005 @@ -133,7 +133,6 @@ print "size before: %s, size after %s" % (curr, simulator.current_size) def test_global_list(self): - curr = simulator.current_size lst = [] def append_to_list(i, j): lst.append([i] * 500) @@ -142,6 +141,15 @@ assert res == 0 for i in range(1, 15): res = interpret(append_to_list, [i, i - 1]) - assert res == i - 1# crashes if constants are not considered roots - + assert res == i - 1 # crashes if constants are not considered roots + def test_string_concatenation(self): + curr = simulator.current_size + def concat(j): + lst = [] + for i in range(j): + lst.append(str(i)) + return len("".join(lst)) + res = interpret(concat, [100]) + assert res == concat(100) + assert simulator.current_size - curr < 16000 From ericvrp at codespeak.net Fri Aug 12 22:09:37 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 12 Aug 2005 22:09:37 +0200 (CEST) Subject: [pypy-svn] r16024 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050812200937.A68AA27B61@code1.codespeak.net> Author: ericvrp Date: Fri Aug 12 22:09:36 2005 New Revision: 16024 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py Log: small fixes and cleanup Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Fri Aug 12 22:09:36 2005 @@ -93,13 +93,16 @@ def phi(self, targetvar, type_, refs, blocknames): assert targetvar.startswith('%') assert refs and len(refs) == len(blocknames), "phi node requires blocks" - for ref in refs: - if targetvar == ref: #some nodes break SSA-form otherwise?!? - return mergelist = ", ".join( ["[%s, %%%s]" % item for item in zip(refs, blocknames)]) - self.indent("%s = phi %s %s" %(targetvar, type_, mergelist)) + s = "%s = phi %s %s" % (targetvar, type_, mergelist) + for ref in refs: + if targetvar == ref: + self.comment('breaks SSA form: ' + s) + break + else: + self.indent(s) def binaryop(self, name, targetvar, type_, ref1, ref2): self.indent("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Fri Aug 12 22:09:36 2005 @@ -73,13 +73,14 @@ extfunctions["%ll_os_fstat"] = ((), """ internal fastcc %structtype.tuple10* %ll_os_fstat(int %fd) { - %st = alloca int, uint 32 - %error = call ccc int %fstat(int %fd, int* %st) - ;TODO XXX if error: raise exception - ;%ret = %ll_stat_result__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed( - %ret = alloca %structtype.tuple10 ;ERROR - store int %s - ret %structtype.tuple10* %ret + ;%st = alloca int, uint 32 + ;%error = call ccc int %fstat(int %fd, int* %st) + ;;TODO XXX if error: raise exception + ;;%ret = %ll_stat_result__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed( + ;%ret = alloca %structtype.tuple10 ;ERROR + ;store int %s + ;ret %structtype.tuple10* %ret + ret %structtype.tuple10* null } """) Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 12 22:09:36 2005 @@ -194,7 +194,7 @@ extfunctions["%int_mod_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ internal fastcc int %%int_mod_ovf_zer(int %%x, int %%y) { %(int_zer_test)s - %%t = rem int %%x, ubyte %%y + %%t = rem int %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_mod_ovf_zer checking From rxe at codespeak.net Fri Aug 12 22:31:13 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 12 Aug 2005 22:31:13 +0200 (CEST) Subject: [pypy-svn] r16025 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050812203113.EB7E727B64@code1.codespeak.net> Author: rxe Date: Fri Aug 12 22:31:12 2005 New Revision: 16025 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: Typo Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Fri Aug 12 22:31:12 2005 @@ -225,7 +225,7 @@ return genllvm(t, **kwds) def compile_function(function, annotation, **kwds): - mod = compile_module(function, annotation) + mod = compile_module(function, annotation, **kwds) return getattr(mod, function.func_name + "_wrapper") def compile_module_function(function, annotation, **kwds): From rxe at codespeak.net Fri Aug 12 23:24:48 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 12 Aug 2005 23:24:48 +0200 (CEST) Subject: [pypy-svn] r16026 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050812212448.AB9AB27B64@code1.codespeak.net> Author: rxe Date: Fri Aug 12 23:24:46 2005 New Revision: 16026 Modified: pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Log: llvm has a different syntax for calls when returning a function pointer it would seem. Quick fix. Thanks to ericvrp for investigating this long standing mystery and thanks to Chris Lattner for his advice. ericvrp: Do we need to do something similar for invoke? Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Fri Aug 12 23:24:46 2005 @@ -307,6 +307,14 @@ else: raise TypeError("cannot represent %r" %(arg,)) + def is_function_ptr(self, arg): + if isinstance(arg, (Constant, Variable)): + arg = arg.concretetype + if isinstance(arg, lltype.Ptr): + if isinstance(arg.TO, lltype.FuncType): + return True + return False + def repr_argwithtype(self, arg): return self.repr_arg(arg), self.repr_arg_type(arg) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Fri Aug 12 23:24:46 2005 @@ -258,6 +258,8 @@ argrefs = self.db.repr_arg_multi(op_args[1:]) argtypes = self.db.repr_arg_type_multi(op_args[1:]) if returntype != "void": + if self.db.is_function_ptr(op.result): + returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) self.codewriter.call(targetvar, returntype, functionref, argrefs, argtypes) else: Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Fri Aug 12 23:24:46 2005 @@ -16,7 +16,6 @@ assert f() == 1 def test_simple_function_pointer(): - py.test.skip("weird casting bug") def f1(x): return x + 1 def f2(x): @@ -27,7 +26,7 @@ def pointersimple(i): return l[i](i) - f = compile_function(pointersimple, [int], True) + f = compile_function(pointersimple, [int]) assert f(0) == pointersimple(0) assert f(1) == pointersimple(1) From tismer at codespeak.net Sat Aug 13 02:41:15 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 13 Aug 2005 02:41:15 +0200 (CEST) Subject: [pypy-svn] r16027 - pypy/dist/pypy/translator/c/src Message-ID: <20050813004115.3234227B64@code1.codespeak.net> Author: tismer Date: Sat Aug 13 02:41:14 2005 New Revision: 16027 Modified: pypy/dist/pypy/translator/c/src/ll_strtod.h Log: correction for C89 standard Modified: pypy/dist/pypy/translator/c/src/ll_strtod.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_strtod.h (original) +++ pypy/dist/pypy/translator/c/src/ll_strtod.h Sat Aug 13 02:41:14 2005 @@ -4,26 +4,24 @@ double LL_strtod_parts_to_float( RPyString *sign, RPyString *beforept, - RPyString *afterpt, - RPyString *exponent) + RPyString *afterpt, + RPyString *exponent) { char *fail_pos; struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - double x; + const char *decimal_point; + int decimal_point_len; + double x; char *last; char *expo = RPyString_AsString(exponent); + int buf_size; + char *s; - if (*expo == '\0') { + if (*expo == '\0') { expo = "0"; - } - - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen(decimal_point); + } - int buf_size = RPyString_Size(sign) + + buf_size = RPyString_Size(sign) + RPyString_Size(beforept) + decimal_point_len + RPyString_Size(afterpt) + @@ -31,29 +29,34 @@ strlen(expo) + 1 /* asciiz */ ; - char *s = malloc(buf_size); - strcpy(s, RPyString_AsString(sign)); + s = malloc(buf_size); + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + strcpy(s, RPyString_AsString(sign)); strcat(s, RPyString_AsString(beforept)); strcat(s, decimal_point); strcat(s, RPyString_AsString(afterpt)); strcat(s, "e"); strcat(s, expo); - last = s + (buf_size-1); - x = strtod(s, &fail_pos); + last = s + (buf_size-1); + x = strtod(s, &fail_pos); errno = 0; free(s); if (fail_pos > last) fail_pos = last; - if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { + if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { RPyRaiseSimpleException(PyExc_ValueError, "invalid float literal"); return -1.0; - } - if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ + } + if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ x = strtod(s, NULL); errno = 0; - } - return x; + } + return x; } From ericvrp at codespeak.net Sat Aug 13 10:49:33 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 13 Aug 2005 10:49:33 +0200 (CEST) Subject: [pypy-svn] r16029 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050813084933.EB44027B64@code1.codespeak.net> Author: ericvrp Date: Sat Aug 13 10:49:33 2005 New Revision: 16029 Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Log: We need to use a different syntax for invoke also (when we return a pointer to a function) Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Sat Aug 13 10:49:33 2005 @@ -30,6 +30,24 @@ assert f(0) == pointersimple(0) assert f(1) == pointersimple(1) +def test_invoke_function_pointer(): + def f1(x): + return x + 1 + def f2(x): + return x + 2 + + l = [f1, f2] + + def invokepointer(i): + try: + return l[i](i) + except: + return 123 + + f = compile_function(invokepointer, [int]) + assert f(0) == invokepointer(0) + assert f(1) == invokepointer(1) + def test_simple_branching(): def simple5(b): if b: From ericvrp at codespeak.net Sat Aug 13 10:51:55 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 13 Aug 2005 10:51:55 +0200 (CEST) Subject: [pypy-svn] r16030 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050813085155.07E1927B64@code1.codespeak.net> Author: ericvrp Date: Sat Aug 13 10:51:54 2005 New Revision: 16030 Modified: pypy/dist/pypy/translator/llvm2/opwriter.py Log: quick fix (identical to what rxe did for calls) for invoke function that returns pointer to function Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Sat Aug 13 10:51:54 2005 @@ -299,6 +299,8 @@ exc_label = block_label + '_exception_handling' if returntype != "void": + if self.db.is_function_ptr(op.result): + returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) self.codewriter.invoke(targetvar, returntype, functionref, argrefs, argtypes, none_label, exc_label) else: From rxe at codespeak.net Sat Aug 13 11:39:35 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 13 Aug 2005 11:39:35 +0200 (CEST) Subject: [pypy-svn] r16031 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050813093935.6588727B64@code1.codespeak.net> Author: rxe Date: Sat Aug 13 11:39:33 2005 New Revision: 16031 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/structnode.py Log: cleanup some XXXs Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Sat Aug 13 11:39:33 2005 @@ -49,9 +49,8 @@ elif isinstance(self.arraytype, lltype.Ptr): return False else: - # XXX Recurse... - return False - + return self.db.is_atomic(self.arraytype) + # ______________________________________________________________________ # entry points from genllvm # @@ -132,20 +131,15 @@ typeval) p, c = lltype.parentlink(self.value) - if p is not None: - assert False, "XXX TODO - but NOT needed by rtyper" + assert p is None, "child arrays are NOT needed by rtyper" return ref def get_pbcref(self, toptr): ref = self.ref p, c = lltype.parentlink(self.value) - if p is not None: - assert False, "XXX TODO - but NOT needed by rtyper" + assert p is None, "child arrays are NOT needed by rtyper" fromptr = "%s*" % self.get_typerepr() - # XXX old version - #refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref) - #ref = "cast(%s %s to %s)" % (fromptr, refptr, toptr) ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) return ref Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Sat Aug 13 11:39:33 2005 @@ -111,25 +111,18 @@ if (isinstance(k, lltype.LowLevelType) or isinstance(k, Constant)): continue - # XXX tmp try blocks - try: - ref = v.get_ref() - except AttributeError, e: - ref = "AttributeError: %s" % e - except AssertionError, e: - ref = "AssertionError: %s" % e - try: - pbc_ref = v.get_ref() - except AttributeError, e: - pbc_ref = "AttributeError: %s" % e - except AssertionError, e: - pbc_ref = "AssertionError: %s" % e assert isinstance(lltype.typeOf(k), lltype.ContainerType) - r += "\ndump_pbcs %s (%s)\n" \ - "getref -> %s \n" \ - "pbcref -> %s \n" % (v, k, ref, pbc_ref) - return r + # Only dump top levels + p, _ = lltype.parentlink(k) + if p is None: + ref = v.get_ref() + pbc_ref = v.get_ref() + + r += "\ndump_pbcs %s (%s)\n" \ + "getref -> %s \n" \ + "pbcref -> %s \n" % (v, k, ref, pbc_ref) + return r #_______create node_____________________________________ @@ -194,7 +187,7 @@ if isinstance(ct, lltype.Array) or isinstance(ct, lltype.Struct): p, c = lltype.parentlink(value) if p is None: - log.prepare_repr_arg("XXX skipping preparing non root", value) + log.prepare_repr_arg("skipping preparing non root", value) return if value is not None: @@ -306,14 +299,6 @@ return self.repr_arg_type(arg.TO) + '*' else: raise TypeError("cannot represent %r" %(arg,)) - - def is_function_ptr(self, arg): - if isinstance(arg, (Constant, Variable)): - arg = arg.concretetype - if isinstance(arg, lltype.Ptr): - if isinstance(arg.TO, lltype.FuncType): - return True - return False def repr_argwithtype(self, arg): return self.repr_arg(arg), self.repr_arg_type(arg) @@ -387,3 +372,17 @@ def get_machine_uword(self): return self.primitives[lltype.Unsigned] + + # __________________________________________________________ + # Other helpers + + def is_function_ptr(self, arg): + if isinstance(arg, (Constant, Variable)): + arg = arg.concretetype + if isinstance(arg, lltype.Ptr): + if isinstance(arg.TO, lltype.FuncType): + return True + return False + + def is_atomic(self, value): + return self.obj2node[value].is_atomic() Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Sat Aug 13 11:39:33 2005 @@ -105,7 +105,6 @@ def getdecl(self): startblock = self.graph.startblock returnblock = self.graph.returnblock - # XXX hack as per remove_voids() startblock_inputargs = [a for a in startblock.inputargs if a.concretetype is not lltype.Void] Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Sat Aug 13 11:39:33 2005 @@ -34,8 +34,7 @@ return False if not isinstance(f, lltype.Primitive): - # XXX Recurse - return False + return self.db.is_atomic(f) return True # ______________________________________________________________________ @@ -71,7 +70,7 @@ # build up a list of indices to get to the last # var-sized struct (or rather the according array) - indices_to_array = [] + indices_to_array = [] current = self.struct while isinstance(current, lltype.Struct): last_pos = len(current._names_without_voids()) - 1 @@ -80,12 +79,15 @@ current = current._flds[name] assert isinstance(current, lltype.Array) arraytype = self.db.repr_arg_type(current.OF) - # XXX write type info as a comment - varsize.write_constructor(self.db, codewriter, - self.ref, self.constructor_decl, arraytype, - indices_to_array, - atomicmalloc=self.is_atomic()) - + # XXX write type info as a comment + varsize.write_constructor(self.db, + codewriter, + self.ref, + self.constructor_decl, + arraytype, + indices_to_array, + atomicmalloc=self.is_atomic()) + class StructNode(ConstantLLVMNode): """ A struct constant. Can simply contain a primitive, @@ -219,9 +221,7 @@ """ Returns a reference as used per pbc. """ ref = self.ref p, c = lltype.parentlink(self.value) - if p is not None: - assert False, "XXX TODO - but NOT needed by rtyper" - + assert p is None, "child arrays are NOT needed by rtyper" fromptr = "%s*" % self.get_typerepr() refptr = "getelementptr (%s %s, int 0)" % (fromptr, ref) ref = "cast(%s %s to %s)" % (fromptr, refptr, toptr) From tismer at codespeak.net Sat Aug 13 15:20:49 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 13 Aug 2005 15:20:49 +0200 (CEST) Subject: [pypy-svn] r16042 - pypy/dist/pypy/translator/c/src Message-ID: <20050813132049.1FB9027B6D@code1.codespeak.net> Author: tismer Date: Sat Aug 13 15:20:48 2005 New Revision: 16042 Modified: pypy/dist/pypy/translator/c/src/ll_strtod.h Log: small glitch Modified: pypy/dist/pypy/translator/c/src/ll_strtod.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_strtod.h (original) +++ pypy/dist/pypy/translator/c/src/ll_strtod.h Sat Aug 13 15:20:48 2005 @@ -21,6 +21,10 @@ expo = "0"; } + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + buf_size = RPyString_Size(sign) + RPyString_Size(beforept) + decimal_point_len + @@ -31,10 +35,6 @@ s = malloc(buf_size); - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen(decimal_point); - strcpy(s, RPyString_AsString(sign)); strcat(s, RPyString_AsString(beforept)); strcat(s, decimal_point); From ericvrp at codespeak.net Sat Aug 13 17:25:41 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 13 Aug 2005 17:25:41 +0200 (CEST) Subject: [pypy-svn] r16048 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050813152541.0F10227B6D@code1.codespeak.net> Author: ericvrp Date: Sat Aug 13 17:25:40 2005 New Revision: 16048 Modified: pypy/dist/pypy/translator/llvm2/module/support.py Log: fixed int_lshift_ovf_val Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Sat Aug 13 17:25:40 2005 @@ -169,7 +169,8 @@ extfunctions["%int_lshift_ovf_val"] = (("%__prepare_OverflowError","%__prepare_ValueError"), """ internal fastcc int %%int_lshift_ovf_val(int %%x, int %%y) { - %%t = shl int %%x, ubyte %%y + %%yu = cast int %%y to ubyte + %%t = shl int %%x, ubyte %%yu %(int_ovf_test)s return_block: ; XXX: TODO int_lshift_ovf_val checking VAL From ericvrp at codespeak.net Sat Aug 13 22:52:34 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 13 Aug 2005 22:52:34 +0200 (CEST) Subject: [pypy-svn] r16052 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050813205234.9BF3527B6D@code1.codespeak.net> Author: ericvrp Date: Sat Aug 13 22:52:33 2005 New Revision: 16052 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py Log: - removed check for SSA breaking, errors were probably caused by not supplying -no-o to translate_pypy.py - added dummy function for the remaining external functions - fixed int_floordiv_ovf_zer, wrong function name was emitted Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Sat Aug 13 22:52:33 2005 @@ -97,12 +97,13 @@ ["[%s, %%%s]" % item for item in zip(refs, blocknames)]) s = "%s = phi %s %s" % (targetvar, type_, mergelist) - for ref in refs: - if targetvar == ref: - self.comment('breaks SSA form: ' + s) - break - else: - self.indent(s) + #for ref in refs: + # if targetvar == ref: + # self.comment('breaks SSA form: ' + s) + # break + #else: + # self.indent(s) + self.indent(s) def binaryop(self, name, targetvar, type_, ref1, ref2): self.indent("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Sat Aug 13 22:52:33 2005 @@ -40,3 +40,38 @@ for params, functions in simple_functions: for function in functions: extfunctions["%ll_math_" + function] = ((), simple_function_template % locals()) + +extfunctions["%ll_math_frexp"] = ((), """ +internal fastcc %structtype.tuple2.6* %ll_math_frexp(double %x) { + ; XXX: TODO: ll_math_frexp + ret %structtype.tuple2.6* null +} +""") + +extfunctions["%ll_math_hypot"] = ((), """ +internal fastcc double %ll_math_hypot(double %x, double %y) { + ; XXX: TODO: ll_math_hypot + ret double 0.0 +} +""") + +extfunctions["%ll_math_ldexp"] = ((), """ +internal fastcc double %ll_math_ldexp(double %x, int %y) { + ; XXX: TODO: ll_math_ldexp + ret double 0.0 +} +""") + +extfunctions["%ll_math_modf"] = ((), """ +internal fastcc %structtype.tuple2.7* %ll_math_modf(double %x) { + ; XXX: TODO: ll_math_modf + ret %structtype.tuple2.7* null +} +""") + +extfunctions["%ll_math_pow"] = ((), """ +internal fastcc double %ll_math_pow(double %x, double %y) { + ; XXX: TODO: ll_math_pow + ret double 0.0 +} +""") Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Sat Aug 13 22:52:33 2005 @@ -85,18 +85,37 @@ """) -#struct stat { -# 0 : dev_t res2 : st_dev; /* device */ -# 1 : ino_t res1 : st_ino; /* inode */ -# 2 : mode_t res0 : st_mode; /* protection */ -# 3 : nlink_t res3 : st_nlink; /* number of hard links */ -# 4 : uid_t res4 : st_uid; /* user ID of owner */ -# 5 : gid_t res5 : st_gid; /* group ID of owner */ -# 6 : dev_t : st_rdev; /* device type (if inode device) */ -# 7 : off_t res6 : st_size; /* total size, in bytes */ -# 8 : blksize_t : st_blksize; /* blocksize for filesystem I/O */ -# 9 : blkcnt_t : st_blocks; /* number of blocks allocated */ -# 10 : time_t res7 : st_atime; /* time of last access */ -# 11 : time_t res8 : st_mtime; /* time of last modification */ -# 12 : time_t res9 : st_ctime; /* time of last status change */ -#}; +extfunctions["%ll_os_ftruncate"] = ((), """ +internal fastcc void %ll_os_ftruncate(int %x, int %y) { + ; XXX: TODO: ll_os_ftruncate + ret void +} +""") + +extfunctions["%ll_os_lseek"] = ((), """ +internal fastcc int %ll_os_lseek(int %x, int %y, int %z) { + ; XXX: TODO: ll_os_lseek + ret int 0 +} +""") + +extfunctions["%ll_os_stat"] = ((), """ +internal fastcc %structtype.tuple10* %ll_os_stat(%structtype.rpy_string* %s) { + ; XXX: TODO: ll_os_stat + ret %structtype.tuple10* null +} +""") + +extfunctions["%ll_strtod_formatd"] = ((), """ +internal fastcc %structtype.rpy_string* %ll_strtod_formatd(%structtype.rpy_string* %s, double %x) { + ; XXX: TODO: ll_strtod_formatd + ret %structtype.rpy_string* null +} +""") + +extfunctions["%"] = ((), """ +internal fastcc double %ll_strtod_parts_to_float(%structtype.rpy_string* s0, %structtype.rpy_string* s1, %structtype.rpy_string* s2, %structtype.rpy_string* s3) { + ; XXX: TODO: ll_strtod_parts_to_float + ret double 0.0 +} +""") Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Sat Aug 13 22:52:33 2005 @@ -182,12 +182,12 @@ #binary with OverflowError and ZeroDivisionError extfunctions["%int_floordiv_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ -internal fastcc int %%int_floordiv_zer_val(int %%x, int %%y) { +internal fastcc int %%int_floordiv_ovf_zer(int %%x, int %%y) { %(int_zer_test)s %%t = div int %%x, %%y %(int_ovf_test)s return_block: - ; XXX: TEST int_floordiv_zer_val checking + ; XXX: TEST int_floordiv_ovf_zer checking ret int %%t } """ % locals()) From tismer at codespeak.net Sat Aug 13 23:36:59 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 13 Aug 2005 23:36:59 +0200 (CEST) Subject: [pypy-svn] r16053 - pypy/dist/pypy/objspace/std Message-ID: <20050813213659.5C46827B6D@code1.codespeak.net> Author: tismer Date: Sat Aug 13 23:36:58 2005 New Revision: 16053 Modified: pypy/dist/pypy/objspace/std/strutil.py Log: provide float datatype to log10 instead of int Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Sat Aug 13 23:36:58 2005 @@ -448,7 +448,7 @@ else: # compute a sufficiently large scale prec = MANTISSA_DIGITS * 2 + 22 # 128, maybe - bits = - (int(math.ceil(-e / math.log10(2) - 1e-10)) + prec) + bits = - (int(math.ceil(-e / math.log10(2.0) - 1e-10)) + prec) w_scale = lshift(space, w_1, mklong(space, -bits)) w_pten = longup(space, w_10, mklong(space, -e), None) w_tmp = multip(space, w_lr, w_scale) From rxe at codespeak.net Sun Aug 14 00:40:05 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 14 Aug 2005 00:40:05 +0200 (CEST) Subject: [pypy-svn] r16054 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050813224005.BD17A27B6A@code1.codespeak.net> Author: rxe Date: Sun Aug 14 00:40:04 2005 New Revision: 16054 Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py pypy/dist/pypy/translator/llvm2/test/test_seq.py Log: Wild goose chase: introduced a test to discover why graphs seem to not be in SSA form (or what SSA form means here http://en.wikipedia.org/wiki/SSA_form) when running translate_pypy. Ironically the problem stemmed from SSI_to_SSA() transformation being run inadvertently via backend_optimizations from translate_pypy. ASIDE - any pointers to any docs relating to acronyms used in the transformation would be much appreciated. Before I read the docstring I assumed it was doing the opposite of what it does. Sorry for my ignorance in this matter. The test was a interesting so checking it in and also reenabled a test which was related to this. Modified: pypy/dist/pypy/translator/llvm2/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_genllvm.py Sun Aug 14 00:40:04 2005 @@ -371,3 +371,45 @@ assert createdict(0,1) == 44 f = compile_function(createdict, [int, int]) assert f(0,1) == createdict(0,1) + +def test_closure(): + class A: + def set(self, x): + self.x = x + def get(self): + return self.x + class B(A): + def get(self): + return A.get(self) * 2 + a = A() + b = B() + def createfn(y): + z = 42 + def fn(x): + return x + y + z + a.get() + b.get() + f2 = lambda: A.get(b) + def getfn(x): + if x % 2: + f = A.get + else: + f = B.get + return f + def proxy(s): + f1 = s.get + t = 0 + for ii in range(5): + f3 = getfn(ii) + t += f1() + t += f2() + t += f3(s) + return t + setattr(B, "f2", proxy) + return fn + fn = createfn(10) + def testf(x): + a.set(10) + b.set(25) + return fn(x) + b.get() + b.f2() + f = compile_function(testf, [int]) + assert f(1) == testf(1) + assert f(2) == testf(2) Modified: pypy/dist/pypy/translator/llvm2/test/test_seq.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_seq.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_seq.py Sun Aug 14 00:40:04 2005 @@ -12,7 +12,6 @@ assert f() == 42 def test_array1(self): - py.test.skip("unknown raison") f = compile_function(llvmsnippet.array_simple1, [int]) assert f(1) == 10 assert f(-42) == -420 From tismer at codespeak.net Sun Aug 14 01:54:57 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 14 Aug 2005 01:54:57 +0200 (CEST) Subject: [pypy-svn] r16056 - pypy/dist/pypy/objspace/std/test Message-ID: <20050813235457.816E727B60@code1.codespeak.net> Author: tismer Date: Sun Aug 14 01:54:56 2005 New Revision: 16056 Modified: pypy/dist/pypy/objspace/std/test/test_longobject.py Log: we can't use overflow values because marshal doesn't handle them correctly in version 1 (string literal) Modified: pypy/dist/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_longobject.py Sun Aug 14 01:54:56 2005 @@ -121,7 +121,10 @@ y = lobj._AsDouble(f1) assert f1.longval() == long(x) # check overflow - x = 12345.6789e10000000000000000000000000000 + #x = 12345.6789e10000000000000000000000000000 + # XXX don't use such consts.Marshal doesn't handle them right. + x = 12345.6789e200 + x *= x assert raises(OverflowError, lobj._FromDouble, self.space, x) # testing Karatsuba stuff From tismer at codespeak.net Sun Aug 14 01:57:01 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 14 Aug 2005 01:57:01 +0200 (CEST) Subject: [pypy-svn] r16057 - pypy/dist/pypy/interpreter Message-ID: <20050813235701.38A3727B60@code1.codespeak.net> Author: tismer Date: Sun Aug 14 01:57:00 2005 New Revision: 16057 Modified: pypy/dist/pypy/interpreter/argument.py Log: a little change to fromshape, since the rtyper barfs on indexing a tuple. Modified: pypy/dist/pypy/interpreter/argument.py ============================================================================== --- pypy/dist/pypy/interpreter/argument.py (original) +++ pypy/dist/pypy/interpreter/argument.py Sun Aug 14 01:57:00 2005 @@ -243,6 +243,8 @@ args_w = data_w[:shape_cnt] p = shape_cnt kwds_w = {} + shape_keys = list(shape_keys) # XXX seems to be needed by the rtyper + # this showed up when I temporarily enabled geninterp for i in range(len(shape_keys)): kwds_w[shape_keys[i]] = data_w[p] p += 1 From tismer at codespeak.net Sun Aug 14 07:03:55 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 14 Aug 2005 07:03:55 +0200 (CEST) Subject: [pypy-svn] r16058 - pypy/dist/pypy/translator/c/test Message-ID: <20050814050355.17FE527B64@code1.codespeak.net> Author: tismer Date: Sun Aug 14 07:03:49 2005 New Revision: 16058 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: made a lot more windows tests pass. there is stillan error with math.exp (incorrect result) which I don't understand. Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Sun Aug 14 07:03:49 2005 @@ -15,13 +15,18 @@ def suggested_primitive_implemented(func): assert func in EXTERNALS, "missing C implementation for %r" % (func,) - +# note: clock synchronizes itself! def test_time_clock(): def does_stuff(): return time.clock() f1 = compile(does_stuff, []) t0 = time.clock() t1 = f1() + t0 = (t0 + time.clock()) / 2.0 + correct = t0 - t1 + # now we can compare! + t0 = time.clock() + t1 = f1() + correct assert type(t1) is float t2 = time.clock() assert t0 <= t1 <= t2 @@ -78,6 +83,8 @@ os.unlink(filename) def test_ftruncate(): + if not hasattr(os, 'ftruncate'): + py.test.skip("this os has no ftruncate :-(") filename = str(udir.join('test_open_read_write_close.txt')) def does_stuff(): fd = os.open(filename, os.O_WRONLY | os.O_CREAT, 0777) @@ -108,16 +115,21 @@ if os.environ.get('PYPY_CC', '').startswith('tcc'): py.test.skip("segfault with tcc :-(") filename = str(py.magic.autopath()) - def call_fstat(): - fd = os.open(filename, os.O_RDONLY, 0777) + fd = os.open(filename, os.O_RDONLY, 0777) + def call_fstat(fd): st = os.fstat(fd) - os.close(fd) return st - f = compile(call_fstat, []) - result = f() - assert result[0] == os.stat(filename)[0] - assert result[1] == os.stat(filename)[1] - assert result[2] == os.stat(filename)[2] + f = compile(call_fstat, [int]) + osstat = os.stat(filename) + result = f(fd) + os.close(fd) + import stat + for i in range(len(result)): + if i == stat.ST_DEV: + continue # does give 3 instead of 0 for windows + elif i == stat.ST_ATIME: + continue # access time will vary + assert (i, result[i]) == (i, osstat[i]) def test_os_isatty(): def call_isatty(fd): @@ -190,7 +202,7 @@ f = compile(fn, [float]) for x in [0.12334, 0.3, 0.5, 0.9883]: print x - assert f(x) == mathfn(x) + assert (funcname, f(x)) == (funcname, mathfn(x)) def test_simple_math_functions(): for funcname in simple_math_functions: From tismer at codespeak.net Sun Aug 14 07:06:16 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 14 Aug 2005 07:06:16 +0200 (CEST) Subject: [pypy-svn] r16059 - pypy/dist/pypy/translator/goal Message-ID: <20050814050616.E4C7127B64@code1.codespeak.net> Author: tismer Date: Sun Aug 14 07:06:14 2005 New Revision: 16059 Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: enabled geninterplevel for targetpypystandalone. This works fine after the small arguments glitch, has about 30% more blocks, and stillworks with less than 400 MB. Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Sun Aug 14 07:06:14 2005 @@ -55,7 +55,7 @@ compiler="pyparseapp", translating=True, #usemodules=['marhsal', '_sre'], - geninterp=False) + geninterp=True) # manually imports app_main.py filename = os.path.join(this_dir, 'app_main.py') From tismer at codespeak.net Sun Aug 14 07:08:53 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 14 Aug 2005 07:08:53 +0200 (CEST) Subject: [pypy-svn] r16060 - in pypy/dist/pypy: interpreter objspace/flow objspace/std translator Message-ID: <20050814050853.A536F27B64@code1.codespeak.net> Author: tismer Date: Sun Aug 14 07:08:51 2005 New Revision: 16060 Modified: pypy/dist/pypy/interpreter/gateway.py pypy/dist/pypy/objspace/flow/specialcase.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/translator/geninterplevel.py Log: disabled storing of any source at all. The app-level compiler package is soo slow, and builtin compilation is so very fast, that I decided to store compiled source, only. This should make the compiled pypymuch quicker on any first error. Accessing a non-existant attribute of something has taken several minutes, most probably because some lazy source code needed to be compiled. Modified: pypy/dist/pypy/interpreter/gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/gateway.py (original) +++ pypy/dist/pypy/interpreter/gateway.py Sun Aug 14 07:08:51 2005 @@ -511,7 +511,10 @@ def __init__(self, source, filename = None, modname = '__builtin__'): self.filename = filename - self.source = source + if self.filename is None: + self.code = py.code.Source(source).compile() + else: + self.code = NiceCompile(self.filename)(source) self.modname = modname # look at the first three lines for a NOT_RPYTHON tag first = "\n".join(source.split("\n", 3)[:3]) @@ -536,7 +539,8 @@ def appcaller(space, *args_w): if not isinstance(space, ObjSpace): raise TypeError("first argument must be a space instance.") - # redirect if the space handles this specially XXX can this be factored a bit less flow space dependetly + # redirect if the space handles this specially + # XXX can this be factored a bit less flow space dependently? if hasattr(space, 'specialcases'): sc = space.specialcases if ApplevelClass in sc: @@ -573,13 +577,8 @@ def build_applevel_dict(self, space): "NOT_RPYTHON" - if self.filename is None: - code = py.code.Source(self.source).compile() - else: - code = NiceCompile(self.filename)(self.source) - from pypy.interpreter.pycode import PyCode - pycode = PyCode(space)._from_code(code, hidden_applevel=self.hidden_applevel) + pycode = PyCode(space)._from_code(self.code, hidden_applevel=self.hidden_applevel) w_glob = space.newdict([]) space.setitem(w_glob, space.wrap('__name__'), space.wrap('__builtin__')) space.exec_(pycode, w_glob, w_glob) @@ -600,10 +599,11 @@ cls._setup() from pypy.translator.geninterplevel import translate_as_module + import marshal scramble = md5.new(cls.seed) - scramble.update(self.source) + scramble.update(marshal.dumps(self.code)) key = scramble.hexdigest() - initfunc = cls.known_source.get(key) + initfunc = cls.known_code.get(key) if not initfunc: # try to get it from file name = key @@ -618,11 +618,11 @@ # print x pass else: - initfunc = cls.known_source[key] + initfunc = cls.known_code[key] if not initfunc: # build it and put it into a file initfunc, newsrc = translate_as_module( - self.source, self.filename, self.modname) + self.code, self.filename, self.modname) fname = cls.cache_path.join(name+".py").strpath f = file(fname, "w") print >> f, """\ @@ -638,8 +638,8 @@ pass""" % name print >> f print >> f, newsrc - print >> f, "from pypy._cache import known_source" - print >> f, "known_source[%r] = %s" % (key, initfunc.__name__) + print >> f, "from pypy._cache import known_code" + print >> f, "known_code[%r] = %s" % (key, initfunc.__name__) w_glob = initfunc(space) return w_glob build_applevelinterp_dict = classmethod(build_applevelinterp_dict) @@ -656,7 +656,7 @@ try: if not ini.check(): raise ImportError # don't import if only a .pyc file left!!! - from pypy._cache import known_source, \ + from pypy._cache import known_code, \ GI_VERSION_RENDERED except ImportError: GI_VERSION_RENDERED = 0 @@ -682,7 +682,7 @@ GI_VERSION_RENDERED = %r -known_source = {} +known_code = {} # self-destruct on double-click: def harakiri(): @@ -700,7 +700,7 @@ del harakiri """ % GI_VERSION) import pypy._cache - cls.known_source = pypy._cache.known_source + cls.known_code = pypy._cache.known_code cls._setup_done = True _setup = classmethod(_setup) Modified: pypy/dist/pypy/objspace/flow/specialcase.py ============================================================================== --- pypy/dist/pypy/objspace/flow/specialcase.py (original) +++ pypy/dist/pypy/objspace/flow/specialcase.py Sun Aug 14 07:08:51 2005 @@ -58,16 +58,12 @@ """NOT_RPYTHON. Called indirectly by ApplevelClass.interphook().appcaller().""" dic = {} - first = "\n".join(app.source.split("\n", 3)[:3]) - if "NOT_RPYTHON" in first: + if not app.can_use_geninterp: return None - if app.filename is None: - code = py.code.Source(app.source).compile() - else: - code = NiceCompile(app.filename)(app.source) + if app.filename is not None: dic['__file__'] = app.filename dic['__name__'] = app.modname - exec code in dic + exec app.code in dic return dic _build = staticmethod(_build) Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sun Aug 14 07:08:51 2005 @@ -141,7 +141,7 @@ import pypy.lib as lib fname = os.path.join(os.path.split(lib.__file__)[0], pyname) fake.filename = fname - fake.source = file(fname).read() + fake.code = compile(file(fname).read(), fname, "exec") fake.modname = publicname w_dic = PyPyCacheDir.build_applevelinterp_dict(fake, self) from pypy.interpreter.module import Module Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Sun Aug 14 07:08:51 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.11' # bump this for substantial changes +GI_VERSION = '1.1.12' # bump this for substantial changes # ____________________________________________________________ try: @@ -1380,10 +1380,14 @@ # and now use the members of the dict """ # create something like a module - if filename is None: - code = py.code.Source(sourcetext).compile() - else: - code = NiceCompile(filename)(sourcetext) + if type(sourcetext) is str: + if filename is None: + code = py.code.Source(sourcetext).compile() + else: + code = NiceCompile(filename)(sourcetext) + else: + # assume we got an already compiled source + code = sourcetext dic = {'__name__': modname} if filename: dic['__file__'] = filename From rxe at codespeak.net Sun Aug 14 16:19:53 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 14 Aug 2005 16:19:53 +0200 (CEST) Subject: [pypy-svn] r16061 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050814141953.3452927B59@code1.codespeak.net> Author: rxe Date: Sun Aug 14 16:19:51 2005 New Revision: 16061 Modified: pypy/dist/pypy/translator/llvm2/opwriter.py Log: Check this in for now. Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Sun Aug 14 16:19:51 2005 @@ -90,7 +90,10 @@ elif op.opname in self.shift_operations: self.shiftop(op) elif op.opname.startswith('cast_'): - self.cast_primitive(op) + if op.opname == 'cast_char_to_int': + self.cast_char_to_int(op) + else: + self.cast_primitive(op) else: meth = getattr(self, op.opname, None) if not meth: @@ -207,6 +210,17 @@ self.db.repr_arg(op.args[0]), tmpvar) + def cast_char_to_int(self, op): + " works for all casts " + assert len(op.args) == 1 + targetvar = self.db.repr_arg(op.result) + targettype = self.db.repr_arg_type(op.result) + fromvar = self.db.repr_arg(op.args[0]) + fromtype = self.db.repr_arg_type(op.args[0]) + intermediate = self.db.repr_tmpvar() + self.codewriter.cast(intermediate, fromtype, fromvar, "ubyte") + self.codewriter.cast(targetvar, "ubyte", intermediate, targettype) + def cast_primitive(self, op): " works for all casts " assert len(op.args) == 1 From tismer at codespeak.net Sun Aug 14 18:27:20 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 14 Aug 2005 18:27:20 +0200 (CEST) Subject: [pypy-svn] r16062 - pypy/dist/pypy/module/marshal Message-ID: <20050814162720.3921427B6E@code1.codespeak.net> Author: tismer Date: Sun Aug 14 18:27:19 2005 New Revision: 16062 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py Log: tested a different dumps buffering scheme, using a list of chars instead of strings. This seems to be a very good thing, marshalling got almost twice as fast, about to reach loads speed. Side note: compared to compiled PyPy, CPython's marshal is very much slower for the test case marshal.dumps(1L << 100000000) Can it be that they have no good buffer allocation, here? For loads, CPython is about 20 times faster ATM. Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Sun Aug 14 18:27:19 2005 @@ -95,7 +95,7 @@ class StringWriter(_BaseWriter): - # actually we are writing to a stringlist + # actually we are writing to a char list def __init__(self): self.buflis = [] @@ -107,20 +107,24 @@ class StringWriter(_BaseWriter): - # actually we are writing to a stringlist + # actually we are writing to a char list def __init__(self): - self.buflis = [''] + self.buflis = [chr(0)] * 128 self.bufpos = 0 def write(self, data): # append is not (yet) efficient, so we do our own allocation #self.buflis.append(data) pos = self.bufpos - if not pos & (pos-1) and pos > 0: - # power of two, double the buffer - self.buflis += self.buflis - self.buflis[pos] = data - self.bufpos = pos + 1 + lng = len(data) + newpos = pos + lng + while len(self.buflis) < newpos: + self.buflis = self.buflis + self.buflis + idx = 0 + while idx < lng: + self.buflis[pos + idx] = data[idx] + idx += 1 + self.bufpos = newpos def get_value(self): return ''.join(self.buflis[:self.bufpos]) From ericvrp at codespeak.net Sun Aug 14 21:33:03 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sun, 14 Aug 2005 21:33:03 +0200 (CEST) Subject: [pypy-svn] r16070 - pypy/dist/pypy/objspace/std Message-ID: <20050814193303.A486627B6D@code1.codespeak.net> Author: ericvrp Date: Sun Aug 14 21:33:03 2005 New Revision: 16070 Modified: pypy/dist/pypy/objspace/std/strutil.py Log: Better to use math.log10(float) consistently. Backends (at least llvm) will have no math.log10(int) implementation. Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Sun Aug 14 21:33:03 2005 @@ -332,7 +332,7 @@ else: # compute a sufficiently large scale prec = MANTISSA_DIGITS * 2 + 22 # 128, maybe - bits = - (int(math.ceil(-e / math.log10(2) - 1e-10)) + prec) + bits = - (int(math.ceil(-e / math.log10(2.0) - 1e-10)) + prec) scale = 2L ** -bits pten = 10L ** -e m = (lr * scale) // pten From tismer at codespeak.net Mon Aug 15 02:41:32 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 15 Aug 2005 02:41:32 +0200 (CEST) Subject: [pypy-svn] r16073 - pypy/dist/pypy/objspace/std Message-ID: <20050815004132.CE8DE27B53@code1.codespeak.net> Author: tismer Date: Mon Aug 15 02:41:31 2005 New Revision: 16073 Modified: pypy/dist/pypy/objspace/std/strutil.py Log: small correction: forgot strip_spaces() Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Mon Aug 15 02:41:31 2005 @@ -10,7 +10,7 @@ # This module is independent from PyPy. def strip_spaces(s): - # XXX this is not locate-dependent + # XXX this is not locale-dependent p = 0 q = len(s) while p < q and s[p] in ' \f\n\r\t\v': @@ -377,6 +377,8 @@ Expects an unwrapped string and return an unwrapped float. """ + s = strip_spaces(s) + if not s: raise OperationError(space.w_ValueError, space.wrap( "empty string for float()")) From tismer at codespeak.net Mon Aug 15 02:43:09 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 15 Aug 2005 02:43:09 +0200 (CEST) Subject: [pypy-svn] r16074 - pypy/dist/pypy/module/marshal Message-ID: <20050815004309.20E3027B53@code1.codespeak.net> Author: tismer Date: Mon Aug 15 02:43:03 2005 New Revision: 16074 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py Log: rewrote the dumps to use a String Marshaller. After the other tests, this looked like the best way. Yes, not urgend, could not resist it. Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Mon Aug 15 02:43:03 2005 @@ -21,12 +21,9 @@ m.put_w_obj(w_data) def dumps(space, w_data, w_version=Py_MARSHAL_VERSION): - # using a list's append directly does not work, - # it leads to someobjectness. - writer = StringWriter() - m = Marshaller(space, writer, space.int_w(w_version)) + m = StringMarshaller(space, space.int_w(w_version)) m.put_w_obj(w_data) - return space.wrap(writer.get_value()) + return space.wrap(m.get_value()) def load(space, w_f): reader = FileReader(space, w_f) @@ -34,28 +31,11 @@ return u.get_w_obj(False) def loads(space, w_str): - reader = StringReader(space, w_str) - u = Unmarshaller(space, reader) - return u.get_w_obj(False) - -# even faster version using inlined string reader -def loads(space, w_str): u = StringUnmarshaller(space, w_str) return u.get_w_obj(False) -class _BaseWriter(object): - pass - - -class _BaseReader(object): - def raise_eof(self): - space = self.space - raise OperationError(space.w_EOFError, space.wrap( - 'EOF read where object expected')) - - -class FileWriter(_BaseWriter): +class FileWriter(object): def __init__(self, space, w_f): self.space = space try: @@ -75,7 +55,7 @@ space.call_function(self.func, space.wrap(data)) -class FileReader(_BaseReader): +class FileReader(object): def __init__(self, space, w_f): self.space = space try: @@ -93,61 +73,10 @@ self.raise_eof() return ret - -class StringWriter(_BaseWriter): - # actually we are writing to a char list - def __init__(self): - self.buflis = [] - - def write(self, data): - self.buflis.append(data) - - def get_value(self): - return ''.join(self.buflis) - - -class StringWriter(_BaseWriter): - # actually we are writing to a char list - def __init__(self): - self.buflis = [chr(0)] * 128 - self.bufpos = 0 - - def write(self, data): - # append is not (yet) efficient, so we do our own allocation - #self.buflis.append(data) - pos = self.bufpos - lng = len(data) - newpos = pos + lng - while len(self.buflis) < newpos: - self.buflis = self.buflis + self.buflis - idx = 0 - while idx < lng: - self.buflis[pos + idx] = data[idx] - idx += 1 - self.bufpos = newpos - - def get_value(self): - return ''.join(self.buflis[:self.bufpos]) - - -class StringReader(_BaseReader): - def __init__(self, space, w_str): - self.space = space - try: - self.bufstr = space.str_w(w_str) - except OperationError: - raise OperationError(space.w_TypeError, space.wrap( - 'marshal.loads() arg must be string')) - self.bufpos = 0 - self.limit = len(self.bufstr) - - def read(self, n): - pos = self.bufpos - newpos = pos + n - if newpos > self.limit: - self.raise_eof() - self.bufpos = newpos - return self.bufstr[pos : newpos] + def raise_eof(self): + space = self.space + raise OperationError(space.w_EOFError, space.wrap( + 'EOF read where object expected')) MAX_MARSHAL_DEPTH = 5000 @@ -189,12 +118,6 @@ * APPLEVEL_STACK_COST + TEST_CONST) self.cpy_nesting = 0 # contribution to compatibility self.stringtable = {} - # since we currently probably can't reach the stringtable (we can't - # find interned strings), try to convince rtyper that this is - #really a string dict. - s = 'hello' - self.stringtable[s] = space.wrap(s) - del self.stringtable[s] self.stackless = False self._stack = None #self._iddict = {} @@ -209,10 +132,13 @@ def put(self, s): self.writer.write(s) + def put1(self, c): + self.writer.write(c) + def atom(self, typecode): #assert type(typecode) is str and len(typecode) == 1 # type(char) not supported - self.put(typecode) + self.put1(typecode) def atom_int(self, typecode, x): a = chr(x & 0xff) @@ -242,7 +168,6 @@ atom_str(tc2, item) def start(self, typecode): - #assert type(typecode) is str and len(typecode) == 1 # type(char) not supported self.put(typecode) @@ -346,6 +271,85 @@ self.raise_exc('object too deeply nested to marshal') +class StringMarshaller(Marshaller): + def __init__(self, space, version): + Marshaller.__init__(self, space, None, version) + self.buflis = [chr(0)] * 128 + self.bufpos = 0 + + def put(self, s): + pos = self.bufpos + lng = len(s) + newpos = pos + lng + while len(self.buflis) < newpos: + self.buflis = self.buflis + self.buflis + idx = 0 + while idx < lng: + self.buflis[pos + idx] = s[idx] + idx += 1 + self.bufpos = newpos + + def put1(self, c): + pos = self.bufpos + newpos = pos + 1 + if len(self.buflis) < newpos: + self.buflis = self.buflis + self.buflis + self.buflis[pos] = c + self.bufpos = newpos + + def atom_int(self, typecode, x): + a = chr(x & 0xff) + x >>= 8 + b = chr(x & 0xff) + x >>= 8 + c = chr(x & 0xff) + x >>= 8 + d = chr(x & 0xff) + pos = self.bufpos + newpos = pos + 5 + if len(self.buflis) < newpos: + self.buflis = self.buflis + self.buflis + self.buflis[pos] = typecode + self.buflis[pos+1] = a + self.buflis[pos+2] = b + self.buflis[pos+3] = c + self.buflis[pos+4] = d + self.bufpos = newpos + + def put_short(self, x): + a = chr(x & 0xff) + x >>= 8 + b = chr(x & 0xff) + pos = self.bufpos + newpos = pos + 2 + if len(self.buflis) < newpos: + self.buflis = self.buflis + self.buflis + self.buflis[pos] = a + self.buflis[pos+1] = b + self.bufpos = newpos + + def put_int(self, x): + a = chr(x & 0xff) + x >>= 8 + b = chr(x & 0xff) + x >>= 8 + c = chr(x & 0xff) + x >>= 8 + d = chr(x & 0xff) + pos = self.bufpos + newpos = pos +4 + if len(self.buflis) < newpos: + self.buflis = self.buflis + self.buflis + self.buflis[pos] = a + self.buflis[pos+1] = b + self.buflis[pos+2] = c + self.buflis[pos+3] = d + self.bufpos = newpos + + def get_value(self): + return ''.join(self.buflis[:self.bufpos]) + + def invalid_typecode(space, u, tc): # %r not supported in rpython #u.raise_exc('invalid typecode in unmarshal: %r' % tc) From tismer at codespeak.net Mon Aug 15 02:46:37 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 15 Aug 2005 02:46:37 +0200 (CEST) Subject: [pypy-svn] r16075 - in pypy/dist/pypy: module/__builtin__ translator Message-ID: <20050815004637.2749B27B53@code1.codespeak.net> Author: tismer Date: Mon Aug 15 02:46:34 2005 New Revision: 16075 Modified: pypy/dist/pypy/module/__builtin__/app_complex.py pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/translator/geninterplevel.py Log: modified gheninterplevel to support properties. With a little hack of storing the property arguments in the __doc__. Don't hesitate to give better proposals. See app_complex how it worked. App_complex is now enabled for interplevel. app_functional could have been, but I get SomeObject--ness in argument.fromshape. Something is not ok here. I left it disabled, but kept the comments. Modified: pypy/dist/pypy/module/__builtin__/app_complex.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_complex.py (original) +++ pypy/dist/pypy/module/__builtin__/app_complex.py Mon Aug 15 02:46:34 2005 @@ -1,11 +1,13 @@ -# NOT_RPYTHON yet """ Plain Python definition of the 'complex' type. """ #XXX Hack: This float is supposed to overflow to inf -OVERFLOWED_FLOAT = float("1e10000000000000000000000000000000") +#OVERFLOWED_FLOAT = float("1e10000000000000000000000000000000") +# but this would crash with marshal v.1.0 +OVERFLOWED_FLOAT = 1e200 +OVERFLOWED_FLOAT *= OVERFLOWED_FLOAT class complex(object): """complex(real[, imag]) -> complex number @@ -376,5 +378,6 @@ imag_slot = complex.imag # make the slots read-only -complex.real = property(real_slot.__get__) -complex.imag = property(imag_slot.__get__) +# XXX added doc string as helper for geninterplevel (any other idea?) +complex.real = property(real_slot.__get__, None, None, 'complex.real.__get__') +complex.imag = property(imag_slot.__get__, None, None, 'complex.imag.__get__') Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Mon Aug 15 02:46:34 2005 @@ -1,4 +1,5 @@ -# NOT_RPYTHON because yield is used +# NOT_RPYTHON because it triggers an annotator error in fromshape +# otherwise it could be geninterped. """ Plain Python definition of the builtin functions oriented towards functional programming. @@ -83,7 +84,7 @@ if not isinstance(c, str_type): raise TypeError("can't filter %s to %s: __getitem__ returned different type", str_type.__name__, str_type.__name__) res.append(c) - return str_type().join(res) + return str_type('').join(res) #added '' to make the annotator happy if function is None: res = [item for item in collection if item] Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Mon Aug 15 02:46:34 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.12' # bump this for substantial changes +GI_VERSION = '1.1.13' # bump this for substantial changes # ____________________________________________________________ try: @@ -528,7 +528,13 @@ name = (name.replace('-', 'minus') .replace('.', 'dot')) name = self.uniquename(name) - self.initcode.append1('%s = space.wrap(%r)' % (name, value)) + # handle overflows + if value != 0.0 and 2*value == value: + self.initcode.append1('float_inf = 1e200\nfloat_inf *= float_inf') + sign = '-+'[value >= 0] + self.initcode.append('%s = space.wrap(%sfloat_inf)' % (name, sign)) + else: + self.initcode.append('%s = space.wrap(%r)' % (name, value)) return name def nameof_str(self, value): @@ -842,7 +848,6 @@ types.ClassType: 'space.w_classobj', types.MethodType: (eval_helper, "instancemethod", "type((lambda:42).__get__(42))"), - property: (eval_helper, "property", 'property'), type(Ellipsis): (eval_helper, 'EllipsisType', 'types.EllipsisType'), builtin_set: (eval_helper, "set", "set"), builtin_frozenset: (eval_helper, "frozenset", "frozenset"), @@ -912,6 +917,23 @@ nameof_method_descriptor = nameof_member_descriptor nameof_wrapper_descriptor = nameof_member_descriptor + def nameof_property(self, prop): + origin = prop.__doc__ # XXX quite a hack + name = self.uniquename('gprop_' + origin) + if not origin: + raise ValueError("sorry, cannot build properties" + " without a helper in __doc__") + # property is lazy loaded app-level as well, trigger it*s creation + self.initcode.append1('space.builtin.get("property") # pull it in') + globname = self.nameof(self.moddict) + self.initcode.append('space.setitem(%s, space.wrap("__builtins__"), ' + 'space.builtin.w_dict)' % globname) + self.initcode.append('%s = space.eval("property(%s)", %s, %s)' %( + name, origin, globname, globname) ) + self.initcode.append('space.delitem(%s, space.wrap("__builtins__"))' + % globname) + return name + def nameof_file(self, fil): if fil is sys.stdin: return 'space.sys.get("stdin")' @@ -1294,9 +1316,10 @@ q = "elif" link = exits[-1] yield "else:" - yield " assert %s == %s" % (self.expr(block.exitswitch, - localscope), - link.exitcase) + # debug only, creates lots of fluffy C code + ##yield " assert %s == %s" % (self.expr(block.exitswitch, + ## localscope), + ## link.exitcase) for op in self.gen_link(exits[-1], localscope, blocknum, block): yield " %s" % op From nik at codespeak.net Mon Aug 15 16:40:38 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Mon, 15 Aug 2005 16:40:38 +0200 (CEST) Subject: [pypy-svn] r16079 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050815144038.BCB7A27B62@code1.codespeak.net> Author: nik Date: Mon Aug 15 16:40:37 2005 New Revision: 16079 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_interp_sre.py Log: moved getlower to interp-level Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Mon Aug 15 16:40:37 2005 @@ -14,10 +14,10 @@ 'copyright': 'app_info.copyright', 'getcodesize': 'app_info.getcodesize', 'compile': 'app_sre.compile', - 'getlower': 'app_sre.getlower', } interpleveldefs = { + 'getlower': 'interp_sre.getlower', '_check_charset': 'interp_sre.check_charset', '_at_dispatch': 'interp_sre.at_dispatch', '_category_dispatch': 'interp_sre.category_dispatch', Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Mon Aug 15 16:40:37 2005 @@ -19,13 +19,6 @@ """Compiles (or rather just converts) a pattern descriptor to a SRE_Pattern object. Actual compilation to opcodes happens in sre_compile.""" return SRE_Pattern(pattern, flags, code, groups, groupindex, indexgroup) - -def getlower(char_ord, flags): - if (char_ord < 128) or (flags & SRE_FLAG_UNICODE) \ - or (flags & SRE_FLAG_LOCALE and char_ord < 256): - return ord(unichr(char_ord).lower()) - else: - return char_ord class SRE_Pattern(object): @@ -455,7 +448,7 @@ self.marks_stack.pop() def lower(self, char_ord): - return getlower(char_ord, self.flags) + return _sre.getlower(char_ord, self.flags) class _MatchContext(object): Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Mon Aug 15 16:40:37 2005 @@ -3,6 +3,23 @@ from pypy.module._sre.app_info import CODESIZE from pypy.module.array.app_array import array +#### Exposed functions + +# XXX can we import those safely from sre_constants? +SRE_FLAG_LOCALE = 4 # honour system locale +SRE_FLAG_UNICODE = 32 # use unicode locale + +def getlower(space, w_char_ord, w_flags): + char_ord = space.int_w(w_char_ord) + flags = space.int_w(w_flags) + if (char_ord < 128) or (flags & SRE_FLAG_UNICODE) \ + or (flags & SRE_FLAG_LOCALE and char_ord < 256): + w_uni_char = space.newunicode([char_ord]) + w_lowered = space.call_method(w_uni_char, "lower") + return space.ord(w_lowered) + else: + return space.wrap(char_ord) + #### Category helpers ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Mon Aug 15 16:40:37 2005 @@ -77,3 +77,6 @@ for string, pos, end in [(".", 0, 1), (".", 1, 1), ("ab", 1, 2)]: assert not isre.at_boundary(space, isre.MatchContext(space, [], space.wrap(string), pos, end)) + +def test_getlower(space): + assert space.int_w(isre.getlower(space, space.wrap(ord("A")), space.wrap(0))) == ord("a") From pedronis at codespeak.net Mon Aug 15 19:30:22 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 15 Aug 2005 19:30:22 +0200 (CEST) Subject: [pypy-svn] r16080 - in pypy/dist/pypy/translator: goal tool tool/pygame Message-ID: <20050815173022.A377A27B73@code1.codespeak.net> Author: pedronis Date: Mon Aug 15 19:30:13 2005 New Revision: 16080 Added: pypy/dist/pypy/translator/tool/port.py - copied, changed from r16078, pypy/dist/pypy/translator/tool/graphserver.py Modified: pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/tool/graphpage.py pypy/dist/pypy/translator/tool/graphserver.py pypy/dist/pypy/translator/tool/pygame/drawgraph.py pypy/dist/pypy/translator/tool/pygame/graphclient.py pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Log: made showg, flowg etc commands work also with translate_pypy acting just as server and a separate display client. the send link info, get page data back pattern has been split to accomodate things Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Mon Aug 15 19:30:13 2005 @@ -240,6 +240,22 @@ someobjnum, num) print "=" * 70 +def worstblocks_topten(ann, n=10): + h = [(count, block) for block, count in ann.reflowcounter.iteritems()] + h.sort() + if not h: + return + print + ansi_print(',----------------------- Top %d Most Reflown Blocks -----------------------.' % n, 36) + for i in range(n): + if not h: + break + count, block = h.pop() + ansi_print(' #%3d: reflown %d times |' % (i+1, count), 36) + about(block) + ansi_print("`----------------------------------------------------------------------------'", 36) + print + def update_usession_dir(stabledir = udir.dirpath('usession')): from py import path @@ -258,32 +274,51 @@ except path.Invalid: print "ignored: couldn't link or copy to %s" % stabledir -def run_in_thread(fn, args, cleanup=None, cleanup_args=()): +def run_debugger_in_thread(fn, args, cleanup=None, cleanup_args=()): def _run_in_thread(): - fn(*args) - if cleanup is not None: - cleanup(*cleanup_args) + try: + try: + fn(*args) + pass # for debugger to land + except pdb.bdb.BdbQuit: + pass + finally: + if cleanup is not None: + cleanup(*cleanup_args) return threading.Thread(target=_run_in_thread, args=()) + +# graph servers + +serv_start, serv_show, serv_stop, serv_cleanup = None, None, None, None + def run_async_server(): + global serv_start, serv_show, serv_stop, serv_cleanup from pypy.translator.tool import graphpage, graphserver homepage = graphpage.TranslatorPage(t) - graphserver.run_server(homepage, port=listen_port, background=True) - options['-text'] = True + (serv_start, serv_show, serv_stop, serv_cleanup + )=graphserver.run_server(homepage, port=listen_port, background=True) + + +def run_server(): + from pypy.translator.tool import graphpage + import pygame + from pypy.translator.tool.pygame.graphclient import get_layout + from pypy.translator.tool.pygame.graphdisplay import GraphDisplay + + if len(t.functions) <= huge: + page = graphpage.TranslatorPage(t) + else: + page = graphpage.LocalizedCallGraphPage(t, entry_point) + + layout = get_layout(page) + + show, async_quit = layout.connexion.initiate_display, layout.connexion.quit + + display = layout.get_display() + + return display.run, show, async_quit, pygame.quit -def worstblocks_topten(ann, n=10): - h = [(count, block) for block, count in ann.reflowcounter.iteritems()] - h.sort() - print - ansi_print(',----------------------- Top %d Most Reflown Blocks -----------------------.' % n, 36) - for i in range(n): - if not h: - break - count, block = h.pop() - ansi_print(' #%3d: reflown %d times |' % (i+1, count), 36) - about(block) - ansi_print("`----------------------------------------------------------------------------'", 36) - print if __name__ == '__main__': @@ -367,26 +402,6 @@ return print "don't know about", x - def run_server(): - from pypy.translator.tool import graphpage - from pypy.translator.tool.pygame.graphclient import get_layout - from pypy.translator.tool.pygame.graphdisplay import GraphDisplay - import pygame - - if not options['-no-mark-some-objects']: - find_someobjects(t, quiet=True) - - if len(t.functions) <= huge: - page = graphpage.TranslatorPage(t) - else: - page = graphpage.LocalizedCallGraphPage(t, entry_point) - - display = GraphDisplay(get_layout(page)) - async_quit = display.async_quit - def show(page): - display.async_cmd(layout=get_layout(page)) - return display.run, show, async_quit, pygame.quit - class PdbPlusShow(pdb.Pdb): def post_mortem(self, t): @@ -533,9 +548,12 @@ if options['-batch']: print >>sys.stderr, "batch mode, not calling interactive helpers" else: - start, show, stop, cleanup = run_server() + if serv_start: + start, show, stop, cleanup = serv_start, serv_show, serv_stop, serv_cleanup + else: + start, show, stop, cleanup = run_server() pdb_plus_show.show = show - debugger = run_in_thread(func, args, stop) + debugger = run_debugger_in_thread(func, args, stop) debugger.start() start() debugger.join() Modified: pypy/dist/pypy/translator/tool/graphpage.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphpage.py (original) +++ pypy/dist/pypy/translator/tool/graphpage.py Mon Aug 15 19:30:13 2005 @@ -32,8 +32,8 @@ def display(self): "Display a graph page locally." - from pypy.translator.tool.pygame.graphclient import get_layout - get_layout(self).display() + from pypy.translator.tool.pygame.graphclient import display_layout + display_layout(self) class SingleGraphPage(GraphPage): Modified: pypy/dist/pypy/translator/tool/graphserver.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphserver.py (original) +++ pypy/dist/pypy/translator/tool/graphserver.py Mon Aug 15 19:30:13 2005 @@ -2,69 +2,75 @@ A socket server for GraphPages. """ -import autopath, sys, thread, struct, marshal +import sys +import autopath +from pypy.translator.tool import port as portutil -def run_server(homepage, port=8888, quiet=False, background=False): - import socket - server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_sock.bind(('', port)) - server_sock.listen(5) - if not quiet: - print >> sys.stderr, 'Accepting connexions on port %d...' % port - def accept_connexions(): - while True: - conn, addr = server_sock.accept() - if not quiet: - print >> sys.stderr, 'Connected by %r.' % (addr,) - thread.start_new_thread(serve_connexion, (conn, homepage)) - if background: - thread.start_new_thread(accept_connexions, ()) - else: - accept_connexions() - - -def recv_all(s, count): - buf = '' - while len(buf) < count: - data = s.recv(count - len(buf)) - if not data: - raise SystemExit # thread exit, rather - buf += data - return buf - -def recv_msg(s): - hdr_size = struct.calcsize("!i") - msg_size, = struct.unpack("!i", recv_all(s, hdr_size)) - msg = recv_all(s, msg_size) - return marshal.loads(msg) - -def send_msg(s, msg): - data = marshal.dumps(msg) - s.sendall(struct.pack("!i", len(data)) + data) - - -def serve_connexion(s, homepage): - pages = {0: homepage} - while True: - key, link = recv_msg(s) - page = pages[key] +send_msg = portutil.send_msg +recv_msg = portutil.recv_msg + +class GraphserverPort(portutil.Port): + + def __init__(self, s, homepage): + portutil.Port.__init__(self, s) + self.pages = {0: homepage} + + def on_msg(self, msg): + if msg is None: + print "Closing %r." % (self.s.getpeername(),) + self.put_msg(None) + return + key, link = msg + page = self.pages[key] if link is not None: try: page = page.content().followlink(link) - key = len(pages) + key = len(self.pages) except KeyError: page = MissingPage() key = -1 - pages[key] = page + self.pages[key] = page page = page.content() reply = { 'key': key, 'dot': page.source, 'links': page.links, } - send_msg(s, reply) + self.put_msg(reply) + + def force_page(self, page): + key = sys.maxint # dummy + self.pages[key] = page + page = page.content() + self.put_msg({ + 'key': key, + 'dot': page.source, + 'links': page.links + }) + +def run_server(homepage, port=8888, quiet=False, background=False): + + last = [None] + + def make_port(s): + gport = GraphserverPort(s, homepage) + last[0] = gport + return gport + + def start(): + pass + + def show(page): # xxx better broadcast in this case? + if last[0]: + last[0].force_page(page) + + def stop(): + pass + + portutil.run_server(make_port, port=port, quiet=quiet, background=background) + return start, show, stop, stop class MissingPage: links = {} Copied: pypy/dist/pypy/translator/tool/port.py (from r16078, pypy/dist/pypy/translator/tool/graphserver.py) ============================================================================== --- pypy/dist/pypy/translator/tool/graphserver.py (original) +++ pypy/dist/pypy/translator/tool/port.py Mon Aug 15 19:30:13 2005 @@ -1,28 +1,8 @@ """ -A socket server for GraphPages. +port on socket, with write-queue-based writer thread and a reader-thread """ -import autopath, sys, thread, struct, marshal - - -def run_server(homepage, port=8888, quiet=False, background=False): - import socket - server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_sock.bind(('', port)) - server_sock.listen(5) - if not quiet: - print >> sys.stderr, 'Accepting connexions on port %d...' % port - def accept_connexions(): - while True: - conn, addr = server_sock.accept() - if not quiet: - print >> sys.stderr, 'Connected by %r.' % (addr,) - thread.start_new_thread(serve_connexion, (conn, homepage)) - if background: - thread.start_new_thread(accept_connexions, ()) - else: - accept_connexions() - +import autopath, sys, thread, struct, marshal, Queue def recv_all(s, count): buf = '' @@ -44,34 +24,53 @@ s.sendall(struct.pack("!i", len(data)) + data) -def serve_connexion(s, homepage): - pages = {0: homepage} - while True: - key, link = recv_msg(s) - page = pages[key] - if link is not None: +class Port: + + def __init__(self, s): + self.s = s + self.writeq = Queue.Queue() + thread.start_new_thread(self.writer, ()) + thread.start_new_thread(self.reader, ()) + + def reader(self): + while True: try: - page = page.content().followlink(link) - key = len(pages) - except KeyError: - page = MissingPage() - key = -1 - pages[key] = page - page = page.content() - reply = { - 'key': key, - 'dot': page.source, - 'links': page.links, - } - send_msg(s, reply) - - -class MissingPage: - links = {} - source = ''' -digraph error { -msg [shape="box", label="Error: a link has gone missing.", color="black", fillcolor="red", style="filled"]; -} -''' - def content(self): - return self + msg = recv_msg(self.s) + except SystemExit: + self.on_msg(None) + raise SystemExit + + self.on_msg(msg) + + def on_msg(self, msg): + pass + + def writer(self): + while True: + msg = self.writeq.get() + if not msg: + raise SystemExit + send_msg(self.s, msg) + + def put_msg(self, msg): + self.writeq.put(msg) + + + +def run_server(port_factory, port=8888, quiet=False, background=False): + import socket + server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_sock.bind(('', port)) + server_sock.listen(5) + if not quiet: + print >> sys.stderr, 'Accepting connexions on port %d...' % port + def accept_connexions(): + while True: + conn, addr = server_sock.accept() + if not quiet: + print >> sys.stderr, 'Connected by %r.' % (addr,) + port_factory(conn) + if background: + thread.start_new_thread(accept_connexions, ()) + else: + accept_connexions() Modified: pypy/dist/pypy/translator/tool/pygame/drawgraph.py ============================================================================== --- pypy/dist/pypy/translator/tool/pygame/drawgraph.py (original) +++ pypy/dist/pypy/translator/tool/pygame/drawgraph.py Mon Aug 15 19:30:13 2005 @@ -75,13 +75,26 @@ break self.links = {} - def display(self): + def get_display(self): from pypy.translator.tool.pygame.graphdisplay import GraphDisplay - GraphDisplay(self).run() + return GraphDisplay(self) + + def display(self): + self.get_display().run() def reload(self): return self +# async interaction helpers + +def display_async_quit(): + pygame.event.post(pygame.event.Event(QUIT)) + +def display_async_cmd(**kwds): + pygame.event.post(pygame.event.Event(USEREVENT, **kwds)) + + + class Node: def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor): self.name = name Modified: pypy/dist/pypy/translator/tool/pygame/graphclient.py ============================================================================== --- pypy/dist/pypy/translator/tool/pygame/graphclient.py (original) +++ pypy/dist/pypy/translator/tool/pygame/graphclient.py Mon Aug 15 19:30:13 2005 @@ -5,7 +5,8 @@ import autopath from pypy.translator.tool.pygame.drawgraph import GraphLayout -from pypy.translator.tool.graphserver import send_msg, recv_msg, MissingPage +from pypy.translator.tool.pygame.drawgraph import display_async_cmd, display_async_quit +from pypy.translator.tool.graphserver import MissingPage, portutil from pypy.tool.udir import udir from py.process import cmdexec @@ -60,16 +61,16 @@ self.key = key self.links.update(links) - def followlink(self, name): - return self.connexion.download(self.key, name) + def request_followlink(self, name): + self.connexion.initiate_display(self.key, name) - def reload(self): - return self.connexion.download(self.key) + def request_reload(self): + self.connexion.initiate_display(self.key) class InProcessConnexion: - def download(self, page, link=None): + def get_layout(self, page, link=None): if link is not None: try: page = page.content().followlink(link) @@ -77,28 +78,49 @@ page = MissingPage() key = page page = page.content() - return ClientGraphLayout(self, key, page.source, page.links) + layout = ClientGraphLayout(self, key, page.source, page.links) + return layout + def initiate_display(self, page, link=None, do_display=False): + layout = self.get_layout(page, link) + if do_display: + layout.display() + else: + display_async_cmd(layout=layout) -class SocketConnexion: - - def __init__(self, s): - self.s = s - - def download(self, key, link=None): - send_msg(self.s, (key, link)) - data = recv_msg(self.s) - return ClientGraphLayout(self, **data) + def quit(self): + display_async_quit() +class SocketConnexion(portutil.Port): -def get_layout(homepage): - return InProcessConnexion().download(homepage) + def initiate_display(self, key, link=None): + self.put_msg((key, link)) + + def on_msg(self, msg): + if msg is None: + self.put_msg(None) + return + + data = msg + layout = ClientGraphLayout(self, **data) + display_async_cmd(layout=layout) + +def get_layout(homepage): # only local + conn = InProcessConnexion() + return conn.get_layout(homepage) + +def display_layout(homepage): + conn = InProcessConnexion() + conn.initiate_display(homepage, do_display=True) -def get_remote_layout(hostname, port=8888): +def display_remote_layout(hostname, port=8888): import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((hostname, port)) - return SocketConnexion(s).download(0) + conn = SocketConnexion(s) + display = ClientGraphLayout(conn, None, "digraph empty {}", {}).get_display() + conn.initiate_display(0) + display.run() if __name__ == '__main__': @@ -110,5 +132,4 @@ sys.exit(2) hostname, port = sys.argv[1].split(':') port = int(port) - layout = get_remote_layout(hostname, port) - layout.display() + display_remote_layout(hostname, port) Modified: pypy/dist/pypy/translator/tool/pygame/graphdisplay.py ============================================================================== --- pypy/dist/pypy/translator/tool/pygame/graphdisplay.py (original) +++ pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Mon Aug 15 19:30:13 2005 @@ -292,11 +292,8 @@ if word in self.layout.links: self.setstatusbar('loading...') self.redraw_now() - newlayout = self.layout.followlink(word) - if newlayout is not None: - self.setlayout(newlayout) - return - self.setstatusbar('') + self.layout.request_followlink(word) + def search(self): searchstr = self.input('Find: ') @@ -341,7 +338,7 @@ self.setstatusbar(msg % item) def setlayout(self, layout): - if self.viewer: + if self.viewer and getattr(self.viewer.graphlayout, 'key', True) is not None: self.viewers_history.append(self.viewer) del self.forward_viewers_history[:] self.layout = layout @@ -415,8 +412,7 @@ def reload(self): self.setstatusbar('reloading...') self.redraw_now() - newlayout = self.layout.reload() - self.setlayout(newlayout) + self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) @@ -470,11 +466,8 @@ if word in self.layout.links: self.setstatusbar('loading...') self.redraw_now() - newlayout = self.layout.followlink(word) - if newlayout is not None: - self.setlayout(newlayout) - return - self.setstatusbar('') + self.layout.request_followlink(word) + return node = self.viewer.node_at_position(pos) if node: self.look_at_node(node) @@ -636,14 +629,11 @@ def process_Quit(self, event): self.quit() - def async_quit(self): - pygame.event.post(pygame.event.Event(QUIT)) - - def async_cmd(self, **kwds): - pygame.event.post(pygame.event.Event(USEREVENT, **kwds)) - - def process_UserEvent(self, event): - self.setlayout(event.layout) + def process_UserEvent(self, event): # new layout request + if event.layout is None: + self.setstatusbar('') + else: + self.setlayout(event.layout) def quit(self): raise StopIteration From rxe at codespeak.net Mon Aug 15 19:57:44 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Mon, 15 Aug 2005 19:57:44 +0200 (CEST) Subject: [pypy-svn] r16081 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050815175744.25BE627B70@code1.codespeak.net> Author: rxe Date: Mon Aug 15 19:57:41 2005 New Revision: 16081 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/structnode.py Log: Basically refactoring and finishing up cleaning up database code in preparation for implementing the external functions via some automation. For those who have been interested in reading database and been postponing it - it is now reached a healthy state (IMHO). ;-) Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Mon Aug 15 19:57:41 2005 @@ -41,7 +41,7 @@ return "" % self.ref def setup(self): - self.db.prepare_repr_arg_type(self.arraytype) + self.db.prepare_type(self.arraytype) def is_atomic(self): if isinstance(self.arraytype, lltype.Primitive): @@ -57,7 +57,7 @@ def writedatatypedecl(self, codewriter): codewriter.arraydef(self.ref, self.db.get_machine_word(), - self.db.repr_arg_type(self.arraytype)) + self.db.repr_type(self.arraytype)) def writedecl(self, codewriter): # declaration for constructor @@ -65,7 +65,7 @@ def writeimpl(self, codewriter): log.writeimpl(self.ref) - fromtype = self.db.repr_arg_type(self.arraytype) + fromtype = self.db.repr_type(self.arraytype) varsize.write_constructor(self.db, codewriter, self.ref, self.constructor_decl, fromtype, @@ -82,6 +82,9 @@ td = "%s = type { %s }" % (self.ref, self.db.get_machine_word()) codewriter.append(td) + def is_atomic(self): + return True + class ArrayNode(ConstantLLVMNode): """ An arraynode. Elements can be a primitive, @@ -120,12 +123,12 @@ def get_typerepr(self): arraylen = self.get_arrayvalue()[0] - typeval = self.db.repr_arg_type(self.arraytype) + typeval = self.db.repr_type(self.arraytype) return "{ %s, [%s x %s] }" % (self.db.get_machine_word(), arraylen, typeval) def get_ref(self): - typeval = self.db.repr_arg_type(lltype.typeOf(self.value)) + typeval = self.db.repr_type(lltype.typeOf(self.value)) ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), self.ref, typeval) @@ -151,7 +154,7 @@ def constantvalue(self): physicallen, arrayrepr = self.get_arrayvalue() - typeval = self.db.repr_arg_type(self.arraytype) + typeval = self.db.repr_type(self.arraytype) # first length is logical, second is physical value = "%s %s, [%s x %s] %s" % (self.db.get_machine_word(), Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Mon Aug 15 19:57:41 2005 @@ -15,7 +15,6 @@ self.n_lines += 1 if self.show_line_numbers: line = "%-75s; %d" % (line, self.n_lines) - #print >> self.f, line self.f.write(line + '\n') def comment(self, line, indent=True): @@ -97,12 +96,6 @@ ["[%s, %%%s]" % item for item in zip(refs, blocknames)]) s = "%s = phi %s %s" % (targetvar, type_, mergelist) - #for ref in refs: - # if targetvar == ref: - # self.comment('breaks SSA form: ' + s) - # break - #else: - # self.indent(s) self.indent(s) def binaryop(self, name, targetvar, type_, ref1, ref2): @@ -158,6 +151,3 @@ res += "sbyte* getelementptr ([%s x sbyte]* %s, int 0, int 0) )" res = res % (tmpname, len, tmpname) self.indent(res) - - #def __str__(self): - # return "\n".join(self._lines) Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Mon Aug 15 19:57:41 2005 @@ -1,3 +1,4 @@ + import sys from pypy.translator.llvm2.log import log from pypy.translator.llvm2.funcnode import FuncNode, FuncTypeNode @@ -9,54 +10,14 @@ from pypy.translator.llvm2.opaquenode import OpaqueNode, OpaqueTypeNode from pypy.translator.llvm2.node import ConstantLLVMNode from pypy.rpython import lltype -from pypy.objspace.flow.model import Block, Constant, Variable -from pypy.rpython.rstr import STR +from pypy.objspace.flow.model import Constant, Variable log = log.database -class NormalizingDict(object): - """ this is a helper dict for obj2node in order - to allow saner key-unification for Ptrs to functions - (and possibly other stuff in the future) - """ - def __init__(self): - self._dict = {} - def __repr__(self): - return repr(self._dict) - def dump(self): - r = "" - for x,y in self._dict.items(): - r += "%s -> %s" % (x, y) - return r - def _get(self, key): - if isinstance(key, Constant): - if isinstance(key.value, lltype._ptr): - key = key.value._obj - return key - def __getitem__(self, key): - key = self._get(key) - return self._dict[key] - def __contains__(self, key): - key = self._get(key) - return key in self._dict - def __setitem__(self, key, value): - key = self._get(key) - self._dict[key] = value - def __delitem__(self, key): - key = self._get(key) - del self._dict[key] - def get(self, key): - key = self._get(key) - return self._dict.get(key) - def values(self): - return self._dict.values() - def items(self): - return self._dict.items() - class Database(object): def __init__(self, translator): self._translator = translator - self.obj2node = NormalizingDict() + self.obj2node = {} self._pendingsetup = [] self._tmpcount = 1 @@ -108,8 +69,7 @@ r = "" for k, v in self.obj2node.items(): - if (isinstance(k, lltype.LowLevelType) or - isinstance(k, Constant)): + if isinstance(k, lltype.LowLevelType): continue assert isinstance(lltype.typeOf(k), lltype.ContainerType) @@ -124,7 +84,7 @@ "pbcref -> %s \n" % (v, k, ref, pbc_ref) return r - #_______create node_____________________________________ + #_______setting up and preperation______________________________ def create_constant_node(self, type_, value): node = None @@ -157,55 +117,23 @@ def addpending(self, key, node): # santity check we at least have a key of the right type assert (isinstance(key, lltype.LowLevelType) or - isinstance(key, Constant) or isinstance(lltype.typeOf(key), lltype.ContainerType)) assert key not in self.obj2node, ( "node with key %r already known!" %(key,)) log("added to pending nodes:", type(key), node) + self.obj2node[key] = node self._pendingsetup.append(node) - def prepare_repr_arg(self, const_or_var): - """if const_or_var is not already in a dictionary self.obj2node, - the appropriate node gets constructed and gets added to - self._pendingsetup and to self.obj2node""" - if const_or_var in self.obj2node: - return - - if isinstance(const_or_var, Constant): - ct = const_or_var.concretetype - if isinstance(ct, lltype.Primitive): - log.prepare(const_or_var, "(is primitive)") - return - - assert isinstance(ct, lltype.Ptr), "Preparation of non primitive and non pointer" - value = const_or_var.value._obj - - # Only prepare root values at this point - if isinstance(ct, lltype.Array) or isinstance(ct, lltype.Struct): - p, c = lltype.parentlink(value) - if p is None: - log.prepare_repr_arg("skipping preparing non root", value) - return - - if value is not None: - self.addpending(const_or_var, self.create_constant_node(ct.TO, value)) - else: - log.prepare(const_or_var, type(const_or_var)) - - def prepare_repr_arg_multi(self, args): - for const_or_var in args: - self.prepare_repr_arg(const_or_var) - - def prepare_repr_arg_type(self, type_): + def prepare_type(self, type_): if type_ in self.obj2node: return if isinstance(type_, lltype.Primitive): pass elif isinstance(type_, lltype.Ptr): - self.prepare_repr_arg_type(type_.TO) + self.prepare_type(type_.TO) elif isinstance(type_, lltype.Struct): if type_._arrayfld: @@ -227,14 +155,9 @@ else: assert False, "need to prepare typerepr %s %s" % (type_, type(type_)) - def prepare_repr_arg_type_multi(self, types): + def prepare_type_multi(self, types): for type_ in types: - self.prepare_repr_arg_type(type_) - - def prepare_arg(self, const_or_var): - log.prepare(const_or_var) - self.prepare_repr_arg_type(const_or_var.concretetype) - self.prepare_repr_arg(const_or_var) + self.prepare_type(type_) def prepare_constant(self, type_, value): if isinstance(type_, lltype.Primitive): @@ -256,16 +179,49 @@ if value not in self.obj2node: self.addpending(value, self.create_constant_node(type_, value)) - # Always add type (it is safe) - self.prepare_repr_arg_type(type_) + # always add type (it is safe) + self.prepare_type(type_) - def setup_all(self, entrynode): - # Constants setup need to be done after the rest - self.entrynode = entrynode + def prepare_arg_value(self, const_or_var): + """if const_or_var is not already in a dictionary self.obj2node, + the appropriate node gets constructed and gets added to + self._pendingsetup and to self.obj2node""" + if isinstance(const_or_var, Constant): + ct = const_or_var.concretetype + if isinstance(ct, lltype.Primitive): + log.prepare(const_or_var, "(is primitive)") + return + + assert isinstance(ct, lltype.Ptr), "Preparation of non primitive and non pointer" + value = const_or_var.value._obj + + # Only prepare root values at this point + if isinstance(ct, lltype.Array) or isinstance(ct, lltype.Struct): + p, c = lltype.parentlink(value) + if p is None: + log.prepare_arg_value("skipping preparing non root", value) + return + + if value is not None and value not in self.obj2node: + self.addpending(value, self.create_constant_node(ct.TO, value)) + else: + assert isinstance(const_or_var, Variable) + + + def prepare_arg(self, const_or_var): + log.prepare(const_or_var) + self.prepare_type(const_or_var.concretetype) + self.prepare_arg_value(const_or_var) + + def setup_all(self, key): + print self.obj2node + entrynode = self.obj2node[key] while self._pendingsetup: node = self._pendingsetup.pop() log.settingup(node) node.setup() + self.entrynode = entrynode + return entrynode def getnodes(self): return self.obj2node.values() @@ -278,7 +234,8 @@ if isinstance(arg.concretetype, lltype.Primitive): return self.primitive_to_str(arg.concretetype, arg.value) else: - node = self.obj2node.get(arg) + assert isinstance(arg.value, lltype._ptr) + node = self.obj2node.get(arg.value._obj) if node is None: return 'null' else: @@ -288,18 +245,21 @@ return "%" + str(arg) def repr_arg_type(self, arg): - if isinstance(arg, (Constant, Variable)): - arg = arg.concretetype + assert isinstance(arg, (Constant, Variable)) + ct = arg.concretetype + return self.repr_type(ct) + + def repr_type(self, type_): try: - return self.obj2node[arg].ref + return self.obj2node[type_].ref except KeyError: - if isinstance(arg, lltype.Primitive): - return self.primitives[arg] - elif isinstance(arg, lltype.Ptr): - return self.repr_arg_type(arg.TO) + '*' + if isinstance(type_, lltype.Primitive): + return self.primitives[type_] + elif isinstance(type_, lltype.Ptr): + return self.repr_type(type_.TO) + '*' else: - raise TypeError("cannot represent %r" %(arg,)) - + raise TypeError("cannot represent %r" %(type_,)) + def repr_argwithtype(self, arg): return self.repr_arg(arg), self.repr_arg_type(arg) @@ -314,10 +274,10 @@ type_ = lltype.typeOf(value) if isinstance(type_, lltype.Primitive): repr = self.primitive_to_str(type_, value) - return None, "%s %s" % (self.repr_arg_type(type_), repr) + return None, "%s %s" % (self.repr_type(type_), repr) elif isinstance(type_, lltype.Ptr): - toptr = self.repr_arg_type(type_) + toptr = self.repr_type(type_) value = value._obj # special case, null pointer @@ -339,6 +299,9 @@ self._tmpcount += 1 return "%tmp." + str(count) + def repr_constructor(self, type_): + return self.obj2node[type_].constructor_ref + # __________________________________________________________ # Primitive stuff @@ -386,3 +349,7 @@ def is_atomic(self, value): return self.obj2node[value].is_atomic() + + def get_childref(self, parent, child): + node = self.obj2node[parent] + return node.get_childref(child) Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Mon Aug 15 19:57:41 2005 @@ -20,12 +20,12 @@ return "" % self.ref def setup(self): - self.db.prepare_repr_arg_type(self.type_.RESULT) - self.db.prepare_repr_arg_type_multi(self.type_._trueargs()) + self.db.prepare_type(self.type_.RESULT) + self.db.prepare_type_multi(self.type_._trueargs()) def writedatatypedecl(self, codewriter): - returntype = self.db.repr_arg_type(self.type_.RESULT) - inputargtypes = self.db.repr_arg_type_multi(self.type_._trueargs()) + returntype = self.db.repr_type(self.type_.RESULT) + inputargtypes = [self.db.repr_type(a) for a in self.type_._trueargs()] codewriter.funcdef(self.ref, returntype, inputargtypes) class FuncNode(ConstantLLVMNode): @@ -90,10 +90,23 @@ blocks = [x for x in flatten(self.graph) if isinstance(x, Block)] for block in blocks: for op in block.operations: - strop = str(op) - l = (len(strop) + 2) # new line & null + strop = str(op) + "\n\x00" + l = len(strop) + if strop.find("direct_call") == -1: + continue tempname = self.db.add_op2comment(l, op) - typeandata = '[%s x sbyte] c"%s\\0A\\00"' % (l, strop) + printables = dict([(ord(i), None) for i in + ("0123456789abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "!#$%&()*+,-./:;<=>?@[\\]^_`{|}~ '")]) + s = [] + for c in strop: + if ord(c) in printables: + s.append(c) + else: + s.append("\\%02x" % ord(c)) + r = 'c"%s"' % "".join(s) + typeandata = '[%s x sbyte] %s' % (l, r) codewriter.globalinstance(tempname, typeandata) def writeglobalconstants(self, codewriter): @@ -162,7 +175,7 @@ else: last_op_index = None for op_index, op in enumerate(block.operations): - if False: # print out debug string + if True: # print out debug string codewriter.newline() codewriter.comment("** %s **" % str(op)) info = self.db.get_op2comment(op) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Mon Aug 15 19:57:41 2005 @@ -6,7 +6,6 @@ from pypy.translator.llvm2.database import Database from pypy.translator.llvm2.pyxwrapper import write_pyx_wrapper from pypy.translator.llvm2.log import log -from pypy.objspace.flow.model import Constant from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir @@ -24,7 +23,7 @@ class GenLLVM(object): - def __init__(self, translator, debug=False): + def __init__(self, translator, debug=True): # reset counters LLVMNode.nodename_count = {} @@ -47,25 +46,22 @@ for ll_helper in (e.ll_exception_match,): ptr = getfunctionptr(self.translator, ll_helper) c = inputconst(lltype.typeOf(ptr), ptr) - self.db.prepare_repr_arg(c) - assert c in self.db.obj2node + self.db.prepare_arg_value(c) ptr = getfunctionptr(self.translator, func) c = inputconst(lltype.typeOf(ptr), ptr) - self.db.prepare_repr_arg(c) - assert c in self.db.obj2node + entry_point = c.value._obj + self.db.prepare_arg_value(c) if self.debug: print 'gen_llvm_source db.setup_all) ' + time.ctime() #7 minutes - self.db.setup_all(self.db.obj2node[c]) + self.entrynode = self.db.setup_all(entry_point) if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) #3 seconds - if self.debug: - log.gen_llvm_source(self.db.dump_pbcs()) - - self.entrynode = self.db.obj2node[c] - + #if self.debug: + # log.gen_llvm_source(self.db.dump_pbcs()) + # prevent running the same function twice in a test if func.func_name in function_count: postfix = '_%d' % function_count[func.func_name] @@ -74,8 +70,8 @@ postfix = '' function_count[func.func_name] = 1 filename = udir.join(func.func_name + postfix).new(ext='.ll') - - codewriter = CodeWriter( open(str(filename),'w') ) + f = open(str(filename),'w') + codewriter = CodeWriter(f) comment = codewriter.comment nl = codewriter.newline @@ -91,10 +87,10 @@ if self.debug: print 'gen_llvm_source typ_decl.writecomments) ' + time.ctime() #0 minutes - if self.debug: - nl(); comment("Comments") ; nl() - for typ_decl in self.db.getnodes(): - typ_decl.writecomments(codewriter) + #if self.debug: + # nl(); comment("Comments") ; nl() + # for typ_decl in self.db.getnodes(): + # typ_decl.writecomments(codewriter) if self.debug: print 'gen_llvm_source extdeclarations) ' + time.ctime() nl(); comment("Function Prototypes") ; nl() @@ -102,8 +98,8 @@ codewriter.append(extdecl) if self.debug: print 'gen_llvm_source self._debug_prototype) ' + time.ctime() - if self.debug: - self._debug_prototype(codewriter) + #if self.debug: + # self._debug_prototype(codewriter) if self.debug: print 'gen_llvm_source typ_decl.writedecl) ' + time.ctime() for typ_decl in self.db.getnodes(): Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Mon Aug 15 19:57:41 2005 @@ -298,7 +298,8 @@ #assert functionref in extfunctions, msg assert len(op_args) >= 1 - assert len(self.block.exits) >= 2 #at least one label and one exception label + # at least one label and one exception label + assert len(self.block.exits) >= 2 link = self.block.exits[0] assert link.exitcase is None @@ -336,8 +337,7 @@ assert issubclass(link.exitcase, Exception) etype = self.db.obj2node[link.llexitcase._obj] - current_exception_type = etype.get_ref() - + current_exception_type = etype.get_ref() target = self.node.block_to_name[link.target] exc_found_label = block_label + '_exception_found_branchto_' + target last_exc_type_var, last_exc_value_var = None, None @@ -388,37 +388,27 @@ self.codewriter.br_uncond(target) def malloc(self, op): + arg_type = op.args[0].value targetvar = self.db.repr_arg(op.result) - arg = op.args[0] - assert (isinstance(arg, Constant) and - isinstance(arg.value, lltype.Struct)) - #XXX unclean - node = self.db.obj2node[arg.value] - type_ = node.ref - self.codewriter.malloc(targetvar, type_, atomic=node.is_atomic()) + + type_ = self.db.repr_type(arg_type) + atomic = self.db.is_atomic(arg_type) + self.codewriter.malloc(targetvar, type_, atomic=atomic) def malloc_varsize(self, op): - targetvar = self.db.repr_arg(op.result) - arg_type = op.args[0] - assert (isinstance(arg_type, Constant) and - isinstance(arg_type.value, (lltype.Array, lltype.Struct))) - - #XXX unclean - node = self.db.obj2node[arg_type.value] - - #XXX AAARRRRRRRRRGFFFFFFFFFFFFGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHH - from pypy.translator.llvm2.arraynode import VoidArrayTypeNode - if isinstance(node, VoidArrayTypeNode): - type_ = node.ref - self.codewriter.malloc(targetvar, type_, atomic=True) + arg_type = op.args[0].value + if isinstance(arg_type, lltype.Array) and arg_type.OF is lltype.Void: + # This is a backend decision to NOT represent a void array with + # anything and save space - therefore not varsizeda anymore + self.malloc(op) return - struct_type = node.ref - struct_cons = node.constructor_ref + targetvar = self.db.repr_arg(op.result) + type_ = self.db.repr_type(arg_type) + "*" + type_cons = self.db.repr_constructor(arg_type) argrefs = self.db.repr_arg_multi(op.args[1:]) argtypes = self.db.repr_arg_type_multi(op.args[1:]) - self.codewriter.call(targetvar, struct_type + "*", struct_cons, - argrefs, argtypes) + self.codewriter.call(targetvar, type_, type_cons, argrefs, argtypes) def _getindexhelper(self, name, struct): assert name in list(struct._names) Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Mon Aug 15 19:57:41 2005 @@ -26,7 +26,7 @@ def setup(self): # Recurse for field in self._fields(): - self.db.prepare_repr_arg_type(field) + self.db.prepare_type(field) def is_atomic(self): for f in self._fields(): @@ -41,9 +41,8 @@ # main entry points from genllvm def writedatatypedecl(self, codewriter): - fields = self._fields() - codewriter.structdef(self.ref, - self.db.repr_arg_type_multi(fields)) + fields_types = [self.db.repr_type(f) for f in self._fields()] + codewriter.structdef(self.ref, fields_types) class StructVarsizeTypeNode(StructTypeNode): @@ -78,8 +77,7 @@ name = current._names_without_voids()[-1] current = current._flds[name] assert isinstance(current, lltype.Array) - arraytype = self.db.repr_arg_type(current.OF) - # XXX write type info as a comment + arraytype = self.db.repr_type(current.OF) varsize.write_constructor(self.db, codewriter, self.ref, @@ -125,7 +123,7 @@ self.db.prepare_constant(lltype.typeOf(p), p) def get_typerepr(self): - return self.db.repr_arg_type(self.structtype) + return self.db.repr_type(self.structtype) def get_childref(self, index): pos = 0 @@ -147,8 +145,7 @@ if p is None: ref = self.ref else: - parent = self.db.obj2node[p] - ref = parent.get_childref(c) + ref = self.db.get_childref(p, c) return ref def get_pbcref(self, toptr): @@ -204,14 +201,14 @@ def get_typerepr(self): # last type is a special case and need to be worked out recursively types = self._gettypes()[:-1] - types_repr = [self.db.repr_arg_type(T) for name, T in types] + types_repr = [self.db.repr_type(T) for name, T in types] types_repr.append(self._get_lastnode().get_typerepr()) return "{%s}" % ", ".join(types_repr) def get_ref(self): ref = super(StructVarsizeNode, self).get_ref() - typeval = self.db.repr_arg_type(lltype.typeOf(self.value)) + typeval = self.db.repr_type(lltype.typeOf(self.value)) ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), ref, typeval) From ericvrp at codespeak.net Mon Aug 15 21:29:28 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 15 Aug 2005 21:29:28 +0200 (CEST) Subject: [pypy-svn] r16082 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050815192928.2B77827B6A@code1.codespeak.net> Author: ericvrp Date: Mon Aug 15 21:29:26 2005 New Revision: 16082 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: - added debug info - added os.stat and os.fstat - enabled some (now passing) tests in test_extfunc.py note: test/test_extfunc.py is not passing tests right now. I think this was not caused by this checkin. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Mon Aug 15 21:29:26 2005 @@ -15,6 +15,10 @@ extfunctions, gc_boehm, gc_disabled, dependencies from pypy.translator.llvm2.node import LLVMNode +#XXX commented out because extfuncs temp. not working +#from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod +#from pypy.rpython.annlowlevel import annotate_lowlevel_helper + from pypy.translator.translator import Translator import time @@ -41,9 +45,20 @@ func = self.translator.entrypoint self.entrypoint = func + #XXX commented out because extfuncs temp. not working + # # make sure helper functions are available + # rtyper = self.translator.rtyper + # for ptr in ( + # #rtyper.annotate_helper(ll_math.ll_frexp_result, [lltype.Float, lltype.Signed]), + # #rtyper.annotate_helper(ll_math.ll_modf_result , [lltype.Float, lltype.Float ]), + # rtyper.annotate_helper(ll_os.ll_stat_result , [lltype.Signed] * 10), + # ): + # c = inputconst(lltype.typeOf(ptr), ptr) + # self.db.prepare_arg_value(c) + # make sure exception matching and exception type are available e = self.translator.rtyper.getexceptiondata() - for ll_helper in (e.ll_exception_match,): + for ll_helper in (e.ll_exception_match, e.ll_raise_OSError): ptr = getfunctionptr(self.translator, ll_helper) c = inputconst(lltype.typeOf(ptr), ptr) self.db.prepare_arg_value(c) @@ -166,6 +181,15 @@ codewriter.append(" ret int %result") codewriter.append("}") codewriter.newline() + # XXX we need to create our own main() that calls the actual entry_point function + entryfunc_name = t[1].split('(')[0] + if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy + codewriter.append("int %main() {") + codewriter.append(" %argv = call fastcc %structtype.list* %ll_newlist__listPtrConst_Signed.2(int 0)") + codewriter.append(" %ret = call fastcc int %entry_point(%structtype.list* %argv)") + codewriter.append(" ret int %ret") + codewriter.append("}") + codewriter.newline() comment("End of file") ; nl() if self.debug: print 'gen_llvm_source return) ' + time.ctime() Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Mon Aug 15 21:29:26 2005 @@ -18,6 +18,12 @@ declare ccc double %tanh(double) declare ccc double %atan2(double,double) declare ccc double %fmod(double,double) + +%__ll_math_frexp = internal constant [12 x sbyte] c"frexp......\\00" +%__ll_math_hypot = internal constant [12 x sbyte] c"hypot......\\00" +%__ll_math_ldexp = internal constant [12 x sbyte] c"ldexp......\\00" +%__ll_math_modf = internal constant [12 x sbyte] c"modf.......\\00" +%__ll_math_pow = internal constant [12 x sbyte] c"pow........\\00" """ extfunctions = {} @@ -41,37 +47,37 @@ for function in functions: extfunctions["%ll_math_" + function] = ((), simple_function_template % locals()) -extfunctions["%ll_math_frexp"] = ((), """ +extfunctions["%ll_math_frexp"] = (("%__debug",), """ internal fastcc %structtype.tuple2.6* %ll_math_frexp(double %x) { - ; XXX: TODO: ll_math_frexp + call fastcc void %__debug([12 x sbyte]* %__ll_math_frexp) ; XXX: TODO: ll_math_frexp ret %structtype.tuple2.6* null } """) -extfunctions["%ll_math_hypot"] = ((), """ +extfunctions["%ll_math_hypot"] = (("%__debug",), """ internal fastcc double %ll_math_hypot(double %x, double %y) { - ; XXX: TODO: ll_math_hypot + call fastcc void %__debug([12 x sbyte]* %__ll_math_hypot) ; XXX: TODO: ll_math_hypot ret double 0.0 } """) -extfunctions["%ll_math_ldexp"] = ((), """ +extfunctions["%ll_math_ldexp"] = (("%__debug",), """ internal fastcc double %ll_math_ldexp(double %x, int %y) { - ; XXX: TODO: ll_math_ldexp + call fastcc void %__debug([12 x sbyte]* %__ll_math_ldexp) ; XXX: TODO: ll_math_ldexp ret double 0.0 } """) -extfunctions["%ll_math_modf"] = ((), """ -internal fastcc %structtype.tuple2.7* %ll_math_modf(double %x) { - ; XXX: TODO: ll_math_modf - ret %structtype.tuple2.7* null +extfunctions["%ll_math_modf"] = (("%__debug",), """ +internal fastcc %structtype.tuple2.9* %ll_math_modf(double %x) { + call fastcc void %__debug([12 x sbyte]* %__ll_math_modf) ; XXX: TODO: ll_math_modf + ret %structtype.tuple2.9* null } """) -extfunctions["%ll_math_pow"] = ((), """ +extfunctions["%ll_math_pow"] = (("%__debug",), """ internal fastcc double %ll_math_pow(double %x, double %y) { - ; XXX: TODO: ll_math_pow + call fastcc void %__debug([12 x sbyte]* %__ll_math_pow) ; XXX: TODO: ll_math_pow ret double 0.0 } """) Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Mon Aug 15 21:29:26 2005 @@ -7,7 +7,17 @@ declare ccc int %read(int, sbyte*, int) declare ccc sbyte* %strncpy(sbyte*, sbyte*, int) declare ccc int %isatty(int) -declare ccc int %fstat(int, int*) +declare ccc int %stat(sbyte*, [32 x int]*) +declare ccc int %fstat(int, [32 x int]*) + +%errno = external global int + +%__ll_os_ftruncate = internal constant [12 x sbyte] c"ftruncate..\\00" +%__ll_os_lseek = internal constant [12 x sbyte] c"lseek......\\00" +%__ll_os_stat = internal constant [12 x sbyte] c"stat.......\\00" +%__ll_os_fstat = internal constant [12 x sbyte] c"fstat......\\00" +%__ll_strtod_formatd = internal constant [12 x sbyte] c"formatd....\\00" +%__ll_strtod_parts_to_float = internal constant [12 x sbyte] c"parts2flt..\\00" """ extfunctions = {} @@ -71,51 +81,171 @@ """) -extfunctions["%ll_os_fstat"] = ((), """ -internal fastcc %structtype.tuple10* %ll_os_fstat(int %fd) { - ;%st = alloca int, uint 32 - ;%error = call ccc int %fstat(int %fd, int* %st) - ;;TODO XXX if error: raise exception - ;;%ret = %ll_stat_result__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed__Signed( - ;%ret = alloca %structtype.tuple10 ;ERROR - ;store int %s - ;ret %structtype.tuple10* %ret - ret %structtype.tuple10* null -} - -""") - -extfunctions["%ll_os_ftruncate"] = ((), """ +extfunctions["%ll_os_ftruncate"] = (("%__debug",), """ internal fastcc void %ll_os_ftruncate(int %x, int %y) { - ; XXX: TODO: ll_os_ftruncate + call fastcc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: TODO: ll_os_ftruncate ret void } """) -extfunctions["%ll_os_lseek"] = ((), """ +extfunctions["%ll_os_lseek"] = (("%__debug",), """ internal fastcc int %ll_os_lseek(int %x, int %y, int %z) { - ; XXX: TODO: ll_os_lseek + call fastcc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: TODO: ll_os_lseek ret int 0 } """) -extfunctions["%ll_os_stat"] = ((), """ +""" +RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) { + long res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; + res0 = (long)st.st_mode; + res1 = (long)st.st_ino; /*XXX HAVE_LARGEFILE_SUPPORT!*/ + res2 = (long)st.st_dev; /*XXX HAVE_LONG_LONG!*/ + res3 = (long)st.st_nlink; + res4 = (long)st.st_uid; + res5 = (long)st.st_gid; + res6 = (long)st.st_size; /*XXX HAVE_LARGEFILE_SUPPORT!*/ + res7 = (long)st.st_atime; /*XXX ignoring quite a lot of things for time here */ + res8 = (long)st.st_mtime; /*XXX ignoring quite a lot of things for time here */ + res9 = (long)st.st_ctime; /*XXX ignoring quite a lot of things for time here */ + /*XXX ignoring BLOCK info here*/ +} + +return ll_stat_result(res0, res1, res2, res3, res4, + res5, res6, res7, res8, res9); +} + +RPySTAT_RESULT* LL_os_stat(RPyString * fname) { + STRUCT_STAT st; + int error = STAT(RPyString_AsString(fname), &st); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + return NULL; + } + return _stat_construct_result_helper(st); +} + +RPySTAT_RESULT* LL_os_fstat(long fd) { + STRUCT_STAT st; + int error = FSTAT(fd, &st); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + return NULL; + } + return _stat_construct_result_helper(st); +} +""" + +extfunctions["%_stat_construct_result_helper"] = ((), """ +internal fastcc %structtype.tuple10* %_stat_construct_result_helper([32 x int]* %src) { + + %src0ptr = getelementptr [32 x int]* %src, int 0, int 4 + %src1ptr = getelementptr [32 x int]* %src, int 0, int 3 + %src2ptr = getelementptr [32 x int]* %src, int 0, int 0 + %src3ptr = getelementptr [32 x int]* %src, int 0, int 5 + %src4ptr = getelementptr [32 x int]* %src, int 0, int 6 + %src5ptr = getelementptr [32 x int]* %src, int 0, int 7 + %src6ptr = getelementptr [32 x int]* %src, int 0, int 11 + %src7ptr = getelementptr [32 x int]* %src, int 0, int 14 + %src8ptr = getelementptr [32 x int]* %src, int 0, int 16 + %src9ptr = getelementptr [32 x int]* %src, int 0, int 18 + + %src0 = load int* %src0ptr + %src1 = load int* %src1ptr + %src2 = load int* %src2ptr + %src3 = load int* %src3ptr + %src4 = load int* %src4ptr + %src5 = load int* %src5ptr + %src6 = load int* %src6ptr + %src7 = load int* %src7ptr + %src8 = load int* %src8ptr + %src9 = load int* %src9ptr + + %malloc.Size.1162 = getelementptr %structtype.tuple10* null, uint 1 + %malloc.SizeU.1162 = cast %structtype.tuple10* %malloc.Size.1162 to uint + %malloc.Ptr.1162 = call fastcc sbyte* %gc_malloc_atomic(uint %malloc.SizeU.1162) + %dest = cast sbyte* %malloc.Ptr.1162 to %structtype.tuple10* + + %dest0ptr = getelementptr [32 x int]* %dest, int 0, int 0 + %dest1ptr = getelementptr [32 x int]* %dest, int 0, int 1 + %dest2ptr = getelementptr [32 x int]* %dest, int 0, int 2 + %dest3ptr = getelementptr [32 x int]* %dest, int 0, int 3 + %dest4ptr = getelementptr [32 x int]* %dest, int 0, int 4 + %dest5ptr = getelementptr [32 x int]* %dest, int 0, int 5 + %dest6ptr = getelementptr [32 x int]* %dest, int 0, int 6 + %dest7ptr = getelementptr [32 x int]* %dest, int 0, int 7 + %dest8ptr = getelementptr [32 x int]* %dest, int 0, int 8 + %dest9ptr = getelementptr [32 x int]* %dest, int 0, int 9 + + store int %src0, int* %dest0ptr + store int %src1, int* %dest1ptr + store int %src2, int* %dest2ptr + store int %src3, int* %dest3ptr + store int %src4, int* %dest4ptr + store int %src5, int* %dest5ptr + store int %src6, int* %dest6ptr + store int %src7, int* %dest7ptr + store int %src8, int* %dest8ptr + store int %src9, int* %dest9ptr + + ret %structtype.tuple10* %dest +} +""") + +extfunctions["%ll_os_stat"] = (("%cast", "%__debug", "%_stat_construct_result_helper"), """ internal fastcc %structtype.tuple10* %ll_os_stat(%structtype.rpy_string* %s) { - ; XXX: TODO: ll_os_stat + + call fastcc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat + + %st = alloca [32 x int] + %filename = call fastcc sbyte* %cast(%structtype.rpy_string* %s) + %error = call ccc int %stat(sbyte* %filename, [32 x int]* %st) + %cond = seteq int %error, 0 + br bool %cond, label %cool, label %bwa + +bwa: + %errno_ = load int* %errno + call fastcc void %ll_raise_OSError__Signed(int %errno_) + ret %structtype.tuple10* null + +cool: + %result = call fastcc %structtype.tuple10* %_stat_construct_result_helper([32 x int]* %st) + ret %structtype.tuple10* %result +} +""") + +extfunctions["%ll_os_fstat"] = (("%__debug",), """ +internal fastcc %structtype.tuple10* %ll_os_fstat(int %fd) { + + call fastcc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat + + %st = alloca [32 x int] + %error = call ccc int %fstat(int %fd, [32 x int]* %st) + %cond = seteq int %error, 0 + br bool %cond, label %cool, label %bwa + +bwa: + %errno_ = load int* %errno + call fastcc void %ll_raise_OSError__Signed(int %errno_) ret %structtype.tuple10* null + +cool: + %result = call fastcc %structtype.tuple10* %_stat_construct_result_helper([32 x int]* %st) + ret %structtype.tuple10* %result } + """) -extfunctions["%ll_strtod_formatd"] = ((), """ +extfunctions["%ll_strtod_formatd"] = (("%__debug",), """ internal fastcc %structtype.rpy_string* %ll_strtod_formatd(%structtype.rpy_string* %s, double %x) { - ; XXX: TODO: ll_strtod_formatd + call fastcc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd ret %structtype.rpy_string* null } """) -extfunctions["%"] = ((), """ +extfunctions["%ll_strtod_parts_to_float"] = (("%__debug",), """ internal fastcc double %ll_strtod_parts_to_float(%structtype.rpy_string* s0, %structtype.rpy_string* s1, %structtype.rpy_string* s2, %structtype.rpy_string* s3) { - ; XXX: TODO: ll_strtod_parts_to_float + call fastcc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float ret double 0.0 } """) Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Mon Aug 15 21:29:26 2005 @@ -1,11 +1,21 @@ extdeclarations = """ declare ccc double %pow(double, double) declare ccc double %fmod(double, double) +declare ccc int %puts(sbyte*) """ extfunctions = {} +extfunctions["%__debug"] = ((), """ +void %__debug([12 x sbyte]* %msg12) { + %msg = getelementptr [12 x sbyte]* %msg12, long 0, long 0 + call int %puts(sbyte* %msg) + ret void +} + +""") + extfunctions["%cast"] = ((), """ internal fastcc sbyte* %cast(%structtype.rpy_string* %structstring) { %source1ptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 1 @@ -15,7 +25,6 @@ """) - #abs functions extfunctions["%int_abs"] = ((), """ internal fastcc int %int_abs(int %x) { Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Mon Aug 15 21:29:26 2005 @@ -95,28 +95,48 @@ # following from translator/c/test/test_extfunc.py Revision: 15320 (jul 29th 2005) def test_os_stat(): - py.test.skip("ll_os_stat not implemented") filename = str(py.magic.autopath()) - def call_stat(n): + def call_stat0(): st = os.stat(filename) - return st[n] - f = compile_function(call_stat, [int]) - assert f(0) == os.stat(filename)[0] - assert f(1) == os.stat(filename)[1] - assert f(2) == os.stat(filename)[2] + return st[0] + def call_stat1(): + st = os.stat(filename) + return st[1] + def call_stat2(): + st = os.stat(filename) + return st[2] + f0 = compile_function(call_stat0, []) + f1 = compile_function(call_stat1, []) + f2 = compile_function(call_stat2, []) + st = os.stat(filename) + assert f0() == st[0] + assert f1() == st[1] + assert f2() == st[2] def test_os_fstat(): - py.test.skip("ll_os_fstat not implemented") filename = str(py.magic.autopath()) - def call_fstat(n): + def call_fstat0(): + fd = os.open(filename, os.O_RDONLY, 0777) + st = os.fstat(fd) + os.close(fd) + return st[0] + def call_fstat1(): + fd = os.open(filename, os.O_RDONLY, 0777) + st = os.fstat(fd) + os.close(fd) + return st[1] + def call_fstat2(): fd = os.open(filename, os.O_RDONLY, 0777) st = os.fstat(fd) os.close(fd) - return st[0] #XXX want to use 0 here! - f = compile_function(call_fstat, [int]) - assert f(0) == os.stat(filename)[0] - assert f(1) == os.stat(filename)[1] - assert f(2) == os.stat(filename)[2] + return st[2] + f0 = compile_function(call_fstat0, []) + f1 = compile_function(call_fstat1, []) + f2 = compile_function(call_fstat2, []) + st = os.stat(filename) + assert f0() == st[0] + assert f1() == st[1] + assert f2() == st[2] def test_getcwd(): py.test.skip("ll_os_getcwd not implemented") @@ -164,7 +184,6 @@ yield math_function_test, funcname def test_os_path_exists(): - py.test.skip("ll_os_stat not implemented") tmpfile = str(udir.join('test_os_path_exists.TMP')) def fn(): return os.path.exists(tmpfile) @@ -175,7 +194,6 @@ assert f() == False def test_os_path_isdir(): - py.test.skip("ll_os_stat not implemented") directory = "./." def fn(): return os.path.isdir(directory) From rxe at codespeak.net Mon Aug 15 21:52:11 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Mon, 15 Aug 2005 21:52:11 +0200 (CEST) Subject: [pypy-svn] r16083 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050815195211.77E0827B5D@code1.codespeak.net> Author: rxe Date: Mon Aug 15 21:52:10 2005 New Revision: 16083 Modified: pypy/dist/pypy/translator/llvm2/extfuncnode.py Log: Oups - missing from last checkin. Modified: pypy/dist/pypy/translator/llvm2/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/extfuncnode.py (original) +++ pypy/dist/pypy/translator/llvm2/extfuncnode.py Mon Aug 15 21:52:10 2005 @@ -13,8 +13,8 @@ def getdecl(self): T = self.value._TYPE - args = [self.db.repr_arg_type(a) for a in T.ARGS] - decl = "%s %s(%s)" % (self.db.repr_arg_type(T.RESULT), + args = [self.db.repr_type(a) for a in T.ARGS] + decl = "%s %s(%s)" % (self.db.repr_type(T.RESULT), self.ref, ", ".join(args)) return decl From ericvrp at codespeak.net Mon Aug 15 21:58:55 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 15 Aug 2005 21:58:55 +0200 (CEST) Subject: [pypy-svn] r16084 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050815195855.8557F27B5D@code1.codespeak.net> Author: ericvrp Date: Mon Aug 15 21:58:54 2005 New Revision: 16084 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/ll_os.py Log: os.stat passes again (fstat not!) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Mon Aug 15 21:58:54 2005 @@ -199,7 +199,7 @@ filename, really_compile=True, standalone=False, - optimize=True, + optimize=False, exe_name=None): if not llvm_is_on_path(): Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Mon Aug 15 21:58:54 2005 @@ -166,16 +166,16 @@ %malloc.Ptr.1162 = call fastcc sbyte* %gc_malloc_atomic(uint %malloc.SizeU.1162) %dest = cast sbyte* %malloc.Ptr.1162 to %structtype.tuple10* - %dest0ptr = getelementptr [32 x int]* %dest, int 0, int 0 - %dest1ptr = getelementptr [32 x int]* %dest, int 0, int 1 - %dest2ptr = getelementptr [32 x int]* %dest, int 0, int 2 - %dest3ptr = getelementptr [32 x int]* %dest, int 0, int 3 - %dest4ptr = getelementptr [32 x int]* %dest, int 0, int 4 - %dest5ptr = getelementptr [32 x int]* %dest, int 0, int 5 - %dest6ptr = getelementptr [32 x int]* %dest, int 0, int 6 - %dest7ptr = getelementptr [32 x int]* %dest, int 0, int 7 - %dest8ptr = getelementptr [32 x int]* %dest, int 0, int 8 - %dest9ptr = getelementptr [32 x int]* %dest, int 0, int 9 + %dest0ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 0 + %dest1ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 1 + %dest2ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 2 + %dest3ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 3 + %dest4ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 4 + %dest5ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 5 + %dest6ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 6 + %dest7ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 7 + %dest8ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 8 + %dest9ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 9 store int %src0, int* %dest0ptr store int %src1, int* %dest1ptr From ericvrp at codespeak.net Mon Aug 15 22:00:27 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 15 Aug 2005 22:00:27 +0200 (CEST) Subject: [pypy-svn] r16085 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050815200027.D377327B5D@code1.codespeak.net> Author: ericvrp Date: Mon Aug 15 22:00:27 2005 New Revision: 16085 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: optimization disabled for now. need to find out why debug output is not shown when enabled Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Mon Aug 15 22:00:27 2005 @@ -199,7 +199,7 @@ filename, really_compile=True, standalone=False, - optimize=False, + optimize=False, #XXX disabled because it breaks things (debug output) exe_name=None): if not llvm_is_on_path(): From ericvrp at codespeak.net Mon Aug 15 22:02:09 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 15 Aug 2005 22:02:09 +0200 (CEST) Subject: [pypy-svn] r16086 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050815200209.B4DA427B5D@code1.codespeak.net> Author: ericvrp Date: Mon Aug 15 22:02:09 2005 New Revision: 16086 Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py Log: os.fstat passes too now. compiling entry_point.ll. to see where we are now.... Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Mon Aug 15 22:02:09 2005 @@ -214,7 +214,7 @@ } """) -extfunctions["%ll_os_fstat"] = (("%__debug",), """ +extfunctions["%ll_os_fstat"] = (("%__debug", "%_stat_construct_result_helper"), """ internal fastcc %structtype.tuple10* %ll_os_fstat(int %fd) { call fastcc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat From pedronis at codespeak.net Mon Aug 15 22:09:03 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 15 Aug 2005 22:09:03 +0200 (CEST) Subject: [pypy-svn] r16087 - pypy/dist/pypy/translator/goal Message-ID: <20050815200903.E3E3827B5D@code1.codespeak.net> Author: pedronis Date: Mon Aug 15 22:09:02 2005 New Revision: 16087 Modified: pypy/dist/pypy/translator/goal/richards.py Log: make classes explicitly new-style Modified: pypy/dist/pypy/translator/goal/richards.py ============================================================================== --- pypy/dist/pypy/translator/goal/richards.py (original) +++ pypy/dist/pypy/translator/goal/richards.py Mon Aug 15 22:09:02 2005 @@ -25,7 +25,7 @@ BUFSIZE_RANGE = range(BUFSIZE) -class Packet: +class Packet(object): def __init__(self,l,i,k): self.link = l self.ident = i @@ -48,7 +48,7 @@ # Task Records -class TaskRec: +class TaskRec(object): pass class DeviceTaskRec(TaskRec): @@ -79,7 +79,7 @@ self.count = 0 # Task -class TaskState: +class TaskState(object): def __init__(self): self.packet_pending = True self.task_waiting = False @@ -142,7 +142,7 @@ TASKTABSIZE = 10 -class TaskWorkArea: +class TaskWorkArea(object): def __init__(self): self.taskTab = [None] * TASKTABSIZE @@ -359,7 +359,7 @@ if tracing: trace(chr(ord("0")+t.ident)) t = t.runTask() -class Richards: +class Richards(object): iterations = 10 From rxe at codespeak.net Mon Aug 15 22:56:57 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Mon, 15 Aug 2005 22:56:57 +0200 (CEST) Subject: [pypy-svn] r16088 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050815205657.E9D7B27B5D@code1.codespeak.net> Author: rxe Date: Mon Aug 15 22:56:56 2005 New Revision: 16088 Modified: pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/genllvm.py Log: A intermediate checkin to get extra info for externs - borrowed from genc. Not sure how much of it we need yet. Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Mon Aug 15 22:56:56 2005 @@ -213,15 +213,16 @@ self.prepare_type(const_or_var.concretetype) self.prepare_arg_value(const_or_var) - def setup_all(self, key): - print self.obj2node - entrynode = self.obj2node[key] + + def setup_all(self): while self._pendingsetup: node = self._pendingsetup.pop() log.settingup(node) node.setup() - self.entrynode = entrynode - return entrynode + + def set_entrynode(self, key): + self.entrynode = self.obj2node[key] + return self.entrynode def getnodes(self): return self.obj2node.values() Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Mon Aug 15 22:56:56 2005 @@ -10,7 +10,7 @@ from pypy.rpython import lltype from pypy.tool.udir import udir from pypy.translator.llvm2.codewriter import CodeWriter -from pypy.translator.llvm2.extfuncnode import ExternalFuncNode +from pypy.translator.llvm2 import extfuncnode from pypy.translator.llvm2.module.extfunction import extdeclarations, \ extfunctions, gc_boehm, gc_disabled, dependencies from pypy.translator.llvm2.node import LLVMNode @@ -34,11 +34,44 @@ self.db = Database(translator) self.translator = translator translator.checkgraphs() - ExternalFuncNode.used_external_functions = {} + extfuncnode.ExternalFuncNode.used_external_functions = {} # for debug we create comments of every operation that may be executed self.debug = debug - + + def _add_to_database(self, name, funcptr): + ptr = getfunctionptr(self.translator, func) + c = inputconst(lltype.typeOf(funcptr), funcptr) + c.value._obj.graph.name = name + self.db.prepare_arg_value(c) + + def post_setup_externs(self): + import types + + rtyper = self.db._translator.rtyper + from pypy.translator.c.extfunc import predeclare_all + + # hacks to make predeclare_all work + self.db.standalone = True + self.db.externalfuncs = {} + decls = list(predeclare_all(self.db, rtyper)) + + for c_name, obj in decls: + if isinstance(obj, lltype.LowLevelType): + self.db.prepare_type(obj) + elif isinstance(obj, types.FunctionType): + funcptr = getfunctionptr(self.translator, obj) + c = inputconst(lltype.typeOf(funcptr), funcptr) + self.db.prepare_arg_value(c) + + elif isinstance(lltype.typeOf(obj), lltype.Ptr): + self.db.prepare_constant(lltype.typeOf(obj), obj) + else: + print "XXX predeclare" , c_name, type(obj), obj + assert False + + return decls + def gen_llvm_source(self, func=None): if self.debug: print 'gen_llvm_source begin) ' + time.ctime() if func is None: @@ -57,22 +90,32 @@ # self.db.prepare_arg_value(c) # make sure exception matching and exception type are available - e = self.translator.rtyper.getexceptiondata() - for ll_helper in (e.ll_exception_match, e.ll_raise_OSError): - ptr = getfunctionptr(self.translator, ll_helper) - c = inputconst(lltype.typeOf(ptr), ptr) - self.db.prepare_arg_value(c) + # XXX Comment out anywat + #e = self.translator.rtyper.getexceptiondata() + #for ll_helper in (e.ll_exception_match, e.ll_raise_OSError): + # ptr = getfunctionptr(self.translator, ll_helper) + # c = inputconst(lltype.typeOf(ptr), ptr) + # self.db.prepare_arg_value(c) ptr = getfunctionptr(self.translator, func) c = inputconst(lltype.typeOf(ptr), ptr) entry_point = c.value._obj self.db.prepare_arg_value(c) - if self.debug: print 'gen_llvm_source db.setup_all) ' + time.ctime() + #if self.debug: print 'gen_llvm_source db.setup_all) ' + time.ctime() #7 minutes - self.entrynode = self.db.setup_all(entry_point) - if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() - if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) + + # set up all nodes + self.db.setup_all() + self.entrynode = self.db.set_entrynode(entry_point) + + # post set up externs + extern_decls = self.post_setup_externs() + self.db._translator.rtyper.specialize_more_blocks() + self.db.setup_all() + + #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() + #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) #3 seconds #if self.debug: # log.gen_llvm_source(self.db.dump_pbcs()) @@ -91,6 +134,19 @@ nl = codewriter.newline nl(); comment("Type Declarations"); nl() + + for c_name, obj in extern_decls: + + if isinstance(obj, lltype.LowLevelType): + if isinstance(obj, lltype.Ptr): + obj = obj.TO + l = "%%%s = type %s" % (c_name, self.db.repr_type(obj)) + codewriter.append(l) + #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + #elif isinstance(obj, types.FunctionType): + # #c.value._obj.graph.name = c_name + # print "XXX predeclare" , c_name, type(obj), obj + for typ_decl in self.db.getnodes(): typ_decl.writedatatypedecl(codewriter) @@ -137,7 +193,7 @@ if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() depdone = {} - for funcname,value in ExternalFuncNode.used_external_functions.iteritems(): + for funcname,value in extfuncnode.ExternalFuncNode.used_external_functions.iteritems(): deps = dependencies(funcname,[]) deps.reverse() for dep in deps: @@ -168,7 +224,7 @@ codewriter.append(" %%result = invoke fastcc %s%%%s to label %%no_exception except label %%exception" % (t[0], t[1])) codewriter.newline() codewriter.append("no_exception:") - codewriter.append(" store %structtype.object_vtable* null, %structtype.object_vtable** %last_exception_type") + codewriter.append(" store %RPYTHON_EXCEPTION_VTABLE* null, %RPYTHON_EXCEPTION_VTABLE** %last_exception_type") codewriter.append(" ret %s%%result" % t[0]) codewriter.newline() codewriter.append("exception:") @@ -176,8 +232,8 @@ codewriter.append("}") codewriter.newline() codewriter.append("ccc int %__entrypoint__raised_LLVMException() {") - codewriter.append(" %tmp = load %structtype.object_vtable** %last_exception_type") - codewriter.append(" %result = cast %structtype.object_vtable* %tmp to int") + codewriter.append(" %tmp = load %RPYTHON_EXCEPTION_VTABLE** %last_exception_type") + codewriter.append(" %result = cast %RPYTHON_EXCEPTION_VTABLE* %tmp to int") codewriter.append(" ret int %result") codewriter.append("}") codewriter.newline() From rxe at codespeak.net Mon Aug 15 23:08:25 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Mon, 15 Aug 2005 23:08:25 +0200 (CEST) Subject: [pypy-svn] r16089 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050815210825.4086A27B58@code1.codespeak.net> Author: rxe Date: Mon Aug 15 23:08:23 2005 New Revision: 16089 Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py Log: Tediously replace all the names with explicit ones. Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Mon Aug 15 23:08:23 2005 @@ -1,13 +1,12 @@ extdeclarations = """;rpython stuff -%structtype.rpy_string = type {int, {int, [0 x sbyte]}} ;gc-type dependent mallocs declare fastcc sbyte* %gc_malloc(uint) declare fastcc sbyte* %gc_malloc_atomic(uint) ;exception handling globals -%last_exception_type = global %structtype.object_vtable* null -%last_exception_value = global %structtype.object* null +%last_exception_type = global %RPYTHON_EXCEPTION_VTABLE* null +%last_exception_value = global %RPYTHON_EXCEPTION* null """ gc_boehm = """declare ccc sbyte* %GC_malloc(uint) Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Mon Aug 15 23:08:23 2005 @@ -48,9 +48,9 @@ extfunctions["%ll_math_" + function] = ((), simple_function_template % locals()) extfunctions["%ll_math_frexp"] = (("%__debug",), """ -internal fastcc %structtype.tuple2.6* %ll_math_frexp(double %x) { +internal fastcc %RPyFREXP_RESULT* %ll_math_frexp(double %x) { call fastcc void %__debug([12 x sbyte]* %__ll_math_frexp) ; XXX: TODO: ll_math_frexp - ret %structtype.tuple2.6* null + ret %RPyFREXP_RESULT* null } """) @@ -69,9 +69,9 @@ """) extfunctions["%ll_math_modf"] = (("%__debug",), """ -internal fastcc %structtype.tuple2.9* %ll_math_modf(double %x) { +internal fastcc %RPyMODF_RESULT* %ll_math_modf(double %x) { call fastcc void %__debug([12 x sbyte]* %__ll_math_modf) ; XXX: TODO: ll_math_modf - ret %structtype.tuple2.9* null + ret %RPyMODF_RESULT* null } """) Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Mon Aug 15 23:08:23 2005 @@ -39,8 +39,8 @@ """) extfunctions["%ll_os_open"] = (("%cast",), """ -internal fastcc int %ll_os_open(%structtype.rpy_string* %structstring, int %flag, int %mode) { - %dest = call fastcc sbyte* %cast(%structtype.rpy_string* %structstring) +internal fastcc int %ll_os_open(%RPyString* %structstring, int %flag, int %mode) { + %dest = call fastcc sbyte* %cast(%RPyString* %structstring) %fd = call ccc int %open(sbyte* %dest, int %flag, int %mode) ret int %fd } @@ -48,10 +48,10 @@ """) extfunctions["%ll_os_write"] = (("%cast",), """ -internal fastcc int %ll_os_write(int %fd, %structtype.rpy_string* %structstring) { - %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 +internal fastcc int %ll_os_write(int %fd, %RPyString* %structstring) { + %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr - %dest = call fastcc sbyte* %cast(%structtype.rpy_string* %structstring) + %dest = call fastcc sbyte* %cast(%RPyString* %structstring) %byteswritten = call ccc int %write(int %fd, sbyte* %dest, int %reallength) ret int %byteswritten } @@ -59,11 +59,11 @@ """) extfunctions["%ll_read_into"] = ((), """ -internal fastcc int %ll_read_into(int %fd, %structtype.rpy_string* %structstring) { - %reallengthptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 0 +internal fastcc int %ll_read_into(int %fd, %RPyString* %structstring) { + %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr - %destptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 1 + %destptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 %dest = cast [0 x sbyte]* %destptr to sbyte* %bytesread = call ccc int %read(int %fd, sbyte* %dest, int %reallength) @@ -137,7 +137,7 @@ """ extfunctions["%_stat_construct_result_helper"] = ((), """ -internal fastcc %structtype.tuple10* %_stat_construct_result_helper([32 x int]* %src) { +internal fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %src) { %src0ptr = getelementptr [32 x int]* %src, int 0, int 4 %src1ptr = getelementptr [32 x int]* %src, int 0, int 3 @@ -161,21 +161,21 @@ %src8 = load int* %src8ptr %src9 = load int* %src9ptr - %malloc.Size.1162 = getelementptr %structtype.tuple10* null, uint 1 - %malloc.SizeU.1162 = cast %structtype.tuple10* %malloc.Size.1162 to uint + %malloc.Size.1162 = getelementptr %RPySTAT_RESULT* null, uint 1 + %malloc.SizeU.1162 = cast %RPySTAT_RESULT* %malloc.Size.1162 to uint %malloc.Ptr.1162 = call fastcc sbyte* %gc_malloc_atomic(uint %malloc.SizeU.1162) - %dest = cast sbyte* %malloc.Ptr.1162 to %structtype.tuple10* + %dest = cast sbyte* %malloc.Ptr.1162 to %RPySTAT_RESULT* - %dest0ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 0 - %dest1ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 1 - %dest2ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 2 - %dest3ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 3 - %dest4ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 4 - %dest5ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 5 - %dest6ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 6 - %dest7ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 7 - %dest8ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 8 - %dest9ptr = getelementptr %structtype.tuple10* %dest, int 0, uint 9 + %dest0ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 0 + %dest1ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 1 + %dest2ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 2 + %dest3ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 3 + %dest4ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 4 + %dest5ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 5 + %dest6ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 6 + %dest7ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 7 + %dest8ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 8 + %dest9ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 9 store int %src0, int* %dest0ptr store int %src1, int* %dest1ptr @@ -188,17 +188,17 @@ store int %src8, int* %dest8ptr store int %src9, int* %dest9ptr - ret %structtype.tuple10* %dest + ret %RPySTAT_RESULT* %dest } """) extfunctions["%ll_os_stat"] = (("%cast", "%__debug", "%_stat_construct_result_helper"), """ -internal fastcc %structtype.tuple10* %ll_os_stat(%structtype.rpy_string* %s) { +internal fastcc %RPySTAT_RESULT* %ll_os_stat(%RPyString* %s) { call fastcc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat %st = alloca [32 x int] - %filename = call fastcc sbyte* %cast(%structtype.rpy_string* %s) + %filename = call fastcc sbyte* %cast(%RPyString* %s) %error = call ccc int %stat(sbyte* %filename, [32 x int]* %st) %cond = seteq int %error, 0 br bool %cond, label %cool, label %bwa @@ -206,16 +206,16 @@ bwa: %errno_ = load int* %errno call fastcc void %ll_raise_OSError__Signed(int %errno_) - ret %structtype.tuple10* null + ret %RPySTAT_RESULT* null cool: - %result = call fastcc %structtype.tuple10* %_stat_construct_result_helper([32 x int]* %st) - ret %structtype.tuple10* %result + %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) + ret %RPySTAT_RESULT* %result } """) extfunctions["%ll_os_fstat"] = (("%__debug", "%_stat_construct_result_helper"), """ -internal fastcc %structtype.tuple10* %ll_os_fstat(int %fd) { +internal fastcc %RPySTAT_RESULT* %ll_os_fstat(int %fd) { call fastcc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat @@ -227,24 +227,24 @@ bwa: %errno_ = load int* %errno call fastcc void %ll_raise_OSError__Signed(int %errno_) - ret %structtype.tuple10* null + ret %RPySTAT_RESULT* null cool: - %result = call fastcc %structtype.tuple10* %_stat_construct_result_helper([32 x int]* %st) - ret %structtype.tuple10* %result + %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) + ret %RPySTAT_RESULT* %result } """) extfunctions["%ll_strtod_formatd"] = (("%__debug",), """ -internal fastcc %structtype.rpy_string* %ll_strtod_formatd(%structtype.rpy_string* %s, double %x) { +internal fastcc %RPyString* %ll_strtod_formatd(%RPyString* %s, double %x) { call fastcc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd - ret %structtype.rpy_string* null + ret %RPyString* null } """) extfunctions["%ll_strtod_parts_to_float"] = (("%__debug",), """ -internal fastcc double %ll_strtod_parts_to_float(%structtype.rpy_string* s0, %structtype.rpy_string* s1, %structtype.rpy_string* s2, %structtype.rpy_string* s3) { +internal fastcc double %ll_strtod_parts_to_float(%RPyString* s0, %RPyString* s1, %RPyString* s2, %RPyString* s3) { call fastcc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float ret double 0.0 } Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Mon Aug 15 23:08:23 2005 @@ -17,8 +17,8 @@ """) extfunctions["%cast"] = ((), """ -internal fastcc sbyte* %cast(%structtype.rpy_string* %structstring) { - %source1ptr = getelementptr %structtype.rpy_string* %structstring, int 0, uint 1, uint 1 +internal fastcc sbyte* %cast(%RPyString* %structstring) { + %source1ptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 %source1 = cast [0 x sbyte]* %source1ptr to sbyte* ret sbyte* %source1 } @@ -61,11 +61,11 @@ for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ internal fastcc void %%__prepare_%(exc)s() { - %%exception_value = call fastcc %%structtype.object* %%instantiate_%(exc)s() - %%tmp = getelementptr %%structtype.object* %%exception_value, int 0, uint 0 - %%exception_type = load %%structtype.object_vtable** %%tmp - store %%structtype.object_vtable* %%exception_type, %%structtype.object_vtable** %%last_exception_type - store %%structtype.object* %%exception_value, %%structtype.object** %%last_exception_value + %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() + %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 + %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp + store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type + store %%RPYTHON_EXCEPTION* %%exception_value, %%RPYTHON_EXCEPTION** %%last_exception_value ret void } """ % locals()) From ericvrp at codespeak.net Mon Aug 15 23:40:53 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 15 Aug 2005 23:40:53 +0200 (CEST) Subject: [pypy-svn] r16090 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050815214053.89E5127B58@code1.codespeak.net> Author: ericvrp Date: Mon Aug 15 23:40:52 2005 New Revision: 16090 Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py Log: ll_os_lseek and ll_os_ftruncate, not test available yet Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Mon Aug 15 23:40:52 2005 @@ -9,6 +9,8 @@ declare ccc int %isatty(int) declare ccc int %stat(sbyte*, [32 x int]*) declare ccc int %fstat(int, [32 x int]*) +declare ccc int %lseek(int, int, int) +declare ccc int %ftruncate(int, int) %errno = external global int @@ -82,16 +84,21 @@ """) extfunctions["%ll_os_ftruncate"] = (("%__debug",), """ -internal fastcc void %ll_os_ftruncate(int %x, int %y) { - call fastcc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: TODO: ll_os_ftruncate +internal fastcc void %ll_os_ftruncate(int %fd, int %length) { + call fastcc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: Test: ll_os_ftruncate + %res = call ccc int %ftruncate(int %fd, int %length) + ;if res < 0 raise... ret void } """) extfunctions["%ll_os_lseek"] = (("%__debug",), """ -internal fastcc int %ll_os_lseek(int %x, int %y, int %z) { - call fastcc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: TODO: ll_os_lseek - ret int 0 +internal fastcc int %ll_os_lseek(int %fd, int %pos, int %how) { + call fastcc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: Test: ll_os_lseek + ;TODO: determine correct %how + %res = call ccc int %lseek(int %fd, int %pos, int %how) + ;if res < 0 raise... + ret int %res } """) From tismer at codespeak.net Tue Aug 16 00:06:49 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 16 Aug 2005 00:06:49 +0200 (CEST) Subject: [pypy-svn] r16091 - pypy/dist/pypy/module/marshal Message-ID: <20050815220649.1491427B5D@code1.codespeak.net> Author: tismer Date: Tue Aug 16 00:06:48 2005 New Revision: 16091 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py Log: explicitly casted get1() to char. Otherwise, even the derived class uses a string! Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Tue Aug 16 00:06:48 2005 @@ -387,7 +387,8 @@ return self.reader.read(n) def get1(self): - return self.get(1) + # convince typer to use a char + return chr(ord(self.get(1))) def atom_str(self, typecode): self.start(typecode) @@ -408,7 +409,6 @@ tc = self.get1() if tc != typecode: self.raise_exc('invalid marshal data') - self.typecode = tc def get_short(self): s = self.get(2) From tismer at codespeak.net Tue Aug 16 00:23:00 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 16 Aug 2005 00:23:00 +0200 (CEST) Subject: [pypy-svn] r16092 - in pypy/dist/pypy: interpreter module/__builtin__ translator Message-ID: <20050815222300.B901F27B70@code1.codespeak.net> Author: tismer Date: Tue Aug 16 00:22:53 2005 New Revision: 16092 Modified: pypy/dist/pypy/interpreter/argument.py pypy/dist/pypy/module/__builtin__/app_functional.py pypy/dist/pypy/translator/geninterplevel.py Log: undid changes to argument.py enabled app_functional for geninterp changed geninterp to pass a proper shape to fromshape that contains a list and no tuple second argument Thanks to Samuele for the hint! Remark: geninterp seems to have pretty low effect (some more than 10%) now. Raw interpretation of code objects seems to be quite close to executing generated code. This might change,again, when we waste less time with refcounting and tiny access functions all ovr the place... Modified: pypy/dist/pypy/interpreter/argument.py ============================================================================== --- pypy/dist/pypy/interpreter/argument.py (original) +++ pypy/dist/pypy/interpreter/argument.py Tue Aug 16 00:22:53 2005 @@ -243,8 +243,6 @@ args_w = data_w[:shape_cnt] p = shape_cnt kwds_w = {} - shape_keys = list(shape_keys) # XXX seems to be needed by the rtyper - # this showed up when I temporarily enabled geninterp for i in range(len(shape_keys)): kwds_w[shape_keys[i]] = data_w[p] p += 1 Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Tue Aug 16 00:22:53 2005 @@ -1,5 +1,3 @@ -# NOT_RPYTHON because it triggers an annotator error in fromshape -# otherwise it could be geninterped. """ Plain Python definition of the builtin functions oriented towards functional programming. @@ -156,11 +154,11 @@ stop = y if not isinstance(start, (int, long)): - raise TypeError('range() interger start argument expected, got %s' % type(start)) + raise TypeError('range() integer start argument expected, got %s' % type(start)) if not isinstance(stop, (int, long)): - raise TypeError('range() interger stop argument expected, got %s' % type(stop)) + raise TypeError('range() integer stop argument expected, got %s' % type(stop)) if not isinstance(step, (int, long)): - raise TypeError('range() interger step argument expected, got %s' % type(step)) + raise TypeError('range() integer step argument expected, got %s' % type(step)) if step == 0: raise ValueError, 'range() arg 3 must not be zero' Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Tue Aug 16 00:22:53 2005 @@ -264,6 +264,8 @@ "%(res)s = space.call_args(%(func)s, _args)") assert isinstance(op.args[1], Constant) shape = op.args[1].value + # make a list out of the second shape elt. + shape = shape[0], list(shape[1]), shape[2], shape[3] return fmt % {"res": self.expr(op.result, localscope), "func": exv, "shape": repr(shape), From tismer at codespeak.net Tue Aug 16 01:39:40 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 16 Aug 2005 01:39:40 +0200 (CEST) Subject: [pypy-svn] r16093 - in pypy/dist/pypy/module: __builtin__ array Message-ID: <20050815233940.95C3C27B70@code1.codespeak.net> Author: tismer Date: Tue Aug 16 01:39:39 2005 New Revision: 16093 Modified: pypy/dist/pypy/module/__builtin__/app_buffer.py pypy/dist/pypy/module/__builtin__/app_help.py pypy/dist/pypy/module/array/app_array.py Log: enabled a few more things for geninterp, with small or no changes Modified: pypy/dist/pypy/module/__builtin__/app_buffer.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_buffer.py (original) +++ pypy/dist/pypy/module/__builtin__/app_buffer.py Tue Aug 16 01:39:39 2005 @@ -1,8 +1,5 @@ -# NOT_RPYTHON (because of array import) # Might probably be deprecated in Python at some point. import sys -from array import array -from struct import pack, unpack class buffer(object): """buffer(object [, offset[, size]]) @@ -14,6 +11,7 @@ """ def __init__(self, object, offset=0, size=None): + import struct, array if isinstance(object, str): pass elif isinstance(object, unicode): @@ -23,11 +21,11 @@ else: pack_code = "I" for char in object: - str_object += pack(pack_code, ord(char)) + str_object += struct.pack(pack_code, ord(char)) object = str_object elif isinstance(object, buffer): object = object.buf - elif isinstance(object, array): + elif isinstance(object, array.array): object = object.tostring() else: raise TypeError, "buffer object expected" Modified: pypy/dist/pypy/module/__builtin__/app_help.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_help.py (original) +++ pypy/dist/pypy/module/__builtin__/app_help.py Tue Aug 16 01:39:39 2005 @@ -1,5 +1,3 @@ -# NOT_RPYTHON - because print is used -# XXX work on enabling print for flow space """ Plain Python definition of the builtin interactive help functions. """ Modified: pypy/dist/pypy/module/array/app_array.py ============================================================================== --- pypy/dist/pypy/module/array/app_array.py (original) +++ pypy/dist/pypy/module/array/app_array.py Tue Aug 16 01:39:39 2005 @@ -1,4 +1,3 @@ -# NOT_RPYTHON """This module defines an object type which can efficiently represent an array of basic values: characters, integers, floating point numbers. Arrays are sequence types and behave very much like lists, From tismer at codespeak.net Tue Aug 16 01:59:37 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 16 Aug 2005 01:59:37 +0200 (CEST) Subject: [pypy-svn] r16094 - pypy/dist/pypy/translator Message-ID: <20050815235937.3963227B5A@code1.codespeak.net> Author: tismer Date: Tue Aug 16 01:59:36 2005 New Revision: 16094 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: had to bump version because of different fromshape() handling Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Tue Aug 16 01:59:36 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.13' # bump this for substantial changes +GI_VERSION = '1.1.14' # bump this for substantial changes # ____________________________________________________________ try: From pedronis at codespeak.net Tue Aug 16 02:29:53 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 16 Aug 2005 02:29:53 +0200 (CEST) Subject: [pypy-svn] r16095 - pypy/dist/pypy/objspace/test Message-ID: <20050816002953.C8F0A27B5D@code1.codespeak.net> Author: pedronis Date: Tue Aug 16 02:29:51 2005 New Revision: 16095 Modified: pypy/dist/pypy/objspace/test/test_traceobjspace.py Log: change test because of more geninterp-ed stuff Modified: pypy/dist/pypy/objspace/test/test_traceobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_traceobjspace.py (original) +++ pypy/dist/pypy/objspace/test/test_traceobjspace.py Tue Aug 16 02:29:51 2005 @@ -47,7 +47,7 @@ filter(None, []) # filter implemented in appspace -> has many more bytecodes res = self.perform_trace(app_f) disresult = pydis.pydis(app_f) - assert len(disresult.bytecodes) < len(list(res.getbytecodes())) + assert len(disresult.bytecodes) <= len(list(res.getbytecodes())) def get_operation(self, iter, optype, name): for op in iter: From tismer at codespeak.net Tue Aug 16 03:01:12 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 16 Aug 2005 03:01:12 +0200 (CEST) Subject: [pypy-svn] r16096 - pypy/dist/pypy/translator/tool Message-ID: <20050816010112.BF36627B5A@code1.codespeak.net> Author: tismer Date: Tue Aug 16 03:01:11 2005 New Revision: 16096 Modified: pypy/dist/pypy/translator/tool/cbuild.py Log: small changes for windows: '.exe' is not needed, comes outomatically from distutils no default library ... and building an exe *works* Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Tue Aug 16 03:01:11 2005 @@ -227,13 +227,12 @@ def build_executable(cfilenames, outputfilename=None, include_dirs=None, - libraries=['m']): + libraries=[]): from distutils.ccompiler import new_compiler - if outputfilename is None: - if sys.platform == 'win32': - ext = '.exe' - else: - ext = '' + if outputfilename is None: + ext = '' + if sys.platform != 'win32': + libraries.append('m') outputfilename = py.path.local(cfilenames[0]).new(ext=ext) else: outputfilename = py.path.local(outputfilename) From tismer at codespeak.net Tue Aug 16 11:57:05 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 16 Aug 2005 11:57:05 +0200 (CEST) Subject: [pypy-svn] r16097 - pypy/dist/pypy/translator/tool Message-ID: <20050816095705.66AA027B58@code1.codespeak.net> Author: tismer Date: Tue Aug 16 11:57:03 2005 New Revision: 16097 Modified: pypy/dist/pypy/translator/tool/cbuild.py Log: small correction to my patch Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Tue Aug 16 11:57:03 2005 @@ -229,10 +229,10 @@ def build_executable(cfilenames, outputfilename=None, include_dirs=None, libraries=[]): from distutils.ccompiler import new_compiler + ext = '' + if sys.platform != 'win32': + libraries.append('m') if outputfilename is None: - ext = '' - if sys.platform != 'win32': - libraries.append('m') outputfilename = py.path.local(cfilenames[0]).new(ext=ext) else: outputfilename = py.path.local(outputfilename) From ericvrp at codespeak.net Tue Aug 16 12:38:47 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 16 Aug 2005 12:38:47 +0200 (CEST) Subject: [pypy-svn] r16098 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050816103847.05E1827B55@code1.codespeak.net> Author: ericvrp Date: Tue Aug 16 12:38:45 2005 New Revision: 16098 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: * some cleaning up (mostly malloc output) * added external function ll_getcwd and str->rpystring casting Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Tue Aug 16 12:38:45 2005 @@ -3,11 +3,8 @@ from pypy.translator.llvm2.log import log from pypy.translator.llvm2.node import LLVMNode, ConstantLLVMNode from pypy.translator.llvm2 import varsize -import itertools log = log.structnode -nextnum = itertools.count().next - class ArrayTypeNode(LLVMNode): def __init__(self, db, array): assert isinstance(array, lltype.Array) @@ -20,7 +17,6 @@ # for the array type in llvm source code # constructor_decl is used to declare the constructor # for the array type (see writeimpl) - c = nextnum() name = "" if isinstance(arraytype, lltype.Ptr): name += "ptr_" Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Tue Aug 16 12:38:45 2005 @@ -13,12 +13,8 @@ from pypy.translator.llvm2.genllvm import use_boehm_gc from pypy.translator.llvm2.log import log -class CompileError(exceptions.Exception): - pass - -SOURCES = "time.ii ".split() - -EXCEPTIONS_SWITCHES = "-enable-correct-eh-support --regalloc iterativescan" +EXCEPTIONS_SWITCHES = "-enable-correct-eh-support" +#--regalloc iterativescan" #unstable (http://llvm.cs.uiuc.edu/docs/ReleaseNotes.html) OPTIMIZATION_SWITCHES = (" ".join([ Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Tue Aug 16 12:38:45 2005 @@ -9,7 +9,6 @@ self.f = f self.show_line_numbers = show_line_number self.n_lines = 0 - self.count = count().next def append(self, line): self.n_lines += 1 @@ -70,6 +69,7 @@ % (intty, cond, defaultdest, labels)) def openfunc(self, decl, is_entrynode=False): + self.malloc_count = count(0).next self.newline() if is_entrynode: linkage_type = '' @@ -127,12 +127,16 @@ "%(fromvar)s to %(targettype)s" % locals()) def malloc(self, targetvar, type_, size=1, atomic=False): - cnt = self.count() + n = self.malloc_count() + if n: + cnt = ".%d" % n + else: + cnt = "" postfix = ('', '_atomic')[atomic] - self.indent("%%malloc.Size.%(cnt)d = getelementptr %(type_)s* null, uint %(size)s" % locals()) - self.indent("%%malloc.SizeU.%(cnt)d = cast %(type_)s* %%malloc.Size.%(cnt)d to uint" % locals()) - self.indent("%%malloc.Ptr.%(cnt)d = call fastcc sbyte* %%gc_malloc%(postfix)s(uint %%malloc.SizeU.%(cnt)d)" % locals()) - self.indent("%(targetvar)s = cast sbyte* %%malloc.Ptr.%(cnt)d to %(type_)s*" % locals()) + self.indent("%%malloc.Size%(cnt)s = getelementptr %(type_)s* null, uint %(size)s" % locals()) + self.indent("%%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to uint" % locals()) + self.indent("%%malloc.Ptr%(cnt)s = call fastcc sbyte* %%gc_malloc%(postfix)s(uint %%malloc.SizeU%(cnt)s)" % locals()) + self.indent("%(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s*" % locals()) def getelementptr(self, targetvar, type, typevar, *indices): res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, int 0, " % locals() Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Tue Aug 16 12:38:45 2005 @@ -6,14 +6,17 @@ declare ccc int %write(int, sbyte*, int) declare ccc int %read(int, sbyte*, int) declare ccc sbyte* %strncpy(sbyte*, sbyte*, int) +declare ccc int %strlen(sbyte*) declare ccc int %isatty(int) declare ccc int %stat(sbyte*, [32 x int]*) declare ccc int %fstat(int, [32 x int]*) declare ccc int %lseek(int, int, int) declare ccc int %ftruncate(int, int) +declare ccc sbyte* %getcwd(sbyte*, int) %errno = external global int +%__ll_os_getcwd = internal constant [12 x sbyte] c"getcwd.....\\00" %__ll_os_ftruncate = internal constant [12 x sbyte] c"ftruncate..\\00" %__ll_os_lseek = internal constant [12 x sbyte] c"lseek......\\00" %__ll_os_stat = internal constant [12 x sbyte] c"stat.......\\00" @@ -32,6 +35,21 @@ """) +extfunctions["%ll_os_getcwd"] = (("%string_to_RPyString", "%__debug"), """ +internal fastcc %RPyString* %ll_os_getcwd() { + + call fastcc void %__debug([12 x sbyte]* %__ll_os_getcwd) ; XXX: Test: ll_os_getcwd + + %s = alloca sbyte, uint 1024 + %res = call ccc sbyte* %getcwd(sbyte* %s, int 1023) + ;if %res == null: raise... + + %cwd = call fastcc %RPyString* %string_to_RPyString(sbyte* %s) + ret %RPyString* %cwd +} + +""") + extfunctions["%ll_os_close"] = ((), """ internal fastcc void %ll_os_close(int %fd) { call ccc void %close(int %fd) @@ -102,60 +120,19 @@ } """) -""" -RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) { - long res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; - res0 = (long)st.st_mode; - res1 = (long)st.st_ino; /*XXX HAVE_LARGEFILE_SUPPORT!*/ - res2 = (long)st.st_dev; /*XXX HAVE_LONG_LONG!*/ - res3 = (long)st.st_nlink; - res4 = (long)st.st_uid; - res5 = (long)st.st_gid; - res6 = (long)st.st_size; /*XXX HAVE_LARGEFILE_SUPPORT!*/ - res7 = (long)st.st_atime; /*XXX ignoring quite a lot of things for time here */ - res8 = (long)st.st_mtime; /*XXX ignoring quite a lot of things for time here */ - res9 = (long)st.st_ctime; /*XXX ignoring quite a lot of things for time here */ - /*XXX ignoring BLOCK info here*/ -} - -return ll_stat_result(res0, res1, res2, res3, res4, - res5, res6, res7, res8, res9); -} - -RPySTAT_RESULT* LL_os_stat(RPyString * fname) { - STRUCT_STAT st; - int error = STAT(RPyString_AsString(fname), &st); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - return NULL; - } - return _stat_construct_result_helper(st); -} - -RPySTAT_RESULT* LL_os_fstat(long fd) { - STRUCT_STAT st; - int error = FSTAT(fd, &st); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - return NULL; - } - return _stat_construct_result_helper(st); -} -""" - extfunctions["%_stat_construct_result_helper"] = ((), """ internal fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %src) { - %src0ptr = getelementptr [32 x int]* %src, int 0, int 4 - %src1ptr = getelementptr [32 x int]* %src, int 0, int 3 - %src2ptr = getelementptr [32 x int]* %src, int 0, int 0 - %src3ptr = getelementptr [32 x int]* %src, int 0, int 5 - %src4ptr = getelementptr [32 x int]* %src, int 0, int 6 - %src5ptr = getelementptr [32 x int]* %src, int 0, int 7 - %src6ptr = getelementptr [32 x int]* %src, int 0, int 11 - %src7ptr = getelementptr [32 x int]* %src, int 0, int 14 - %src8ptr = getelementptr [32 x int]* %src, int 0, int 16 - %src9ptr = getelementptr [32 x int]* %src, int 0, int 18 + %src0ptr = getelementptr [32 x int]* %src, int 0, uint 4 ;st_mode + %src1ptr = getelementptr [32 x int]* %src, int 0, uint 3 ;st_ino + %src2ptr = getelementptr [32 x int]* %src, int 0, uint 0 ;st_dev + %src3ptr = getelementptr [32 x int]* %src, int 0, uint 5 ;st_nlink + %src4ptr = getelementptr [32 x int]* %src, int 0, uint 6 ;st_uid + %src5ptr = getelementptr [32 x int]* %src, int 0, uint 7 ;st_gid + %src6ptr = getelementptr [32 x int]* %src, int 0, uint 11 ;st_size + %src7ptr = getelementptr [32 x int]* %src, int 0, uint 14 ;st_atime + %src8ptr = getelementptr [32 x int]* %src, int 0, uint 16 ;st_mtime + %src9ptr = getelementptr [32 x int]* %src, int 0, uint 18 ;st_ctime %src0 = load int* %src0ptr %src1 = load int* %src1ptr @@ -168,10 +145,10 @@ %src8 = load int* %src8ptr %src9 = load int* %src9ptr - %malloc.Size.1162 = getelementptr %RPySTAT_RESULT* null, uint 1 - %malloc.SizeU.1162 = cast %RPySTAT_RESULT* %malloc.Size.1162 to uint - %malloc.Ptr.1162 = call fastcc sbyte* %gc_malloc_atomic(uint %malloc.SizeU.1162) - %dest = cast sbyte* %malloc.Ptr.1162 to %RPySTAT_RESULT* + %malloc.Size = getelementptr %RPySTAT_RESULT* null, uint 1 + %malloc.SizeU = cast %RPySTAT_RESULT* %malloc.Size to uint + %malloc.Ptr = call fastcc sbyte* %gc_malloc_atomic(uint %malloc.SizeU) + %dest = cast sbyte* %malloc.Ptr to %RPySTAT_RESULT* %dest0ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 0 %dest1ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 1 Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Tue Aug 16 12:38:45 2005 @@ -25,6 +25,20 @@ """) +extfunctions["%string_to_RPyString"] = ((), """ +internal fastcc %RPyString* %string_to_RPyString(sbyte* %s) { + %len = call ccc int %strlen(sbyte* %s) + %rpy = call fastcc %RPyString* %RPyString_New__Signed(int %len) + %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 + %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* + + call ccc sbyte* %strncpy(sbyte* %rpystr, sbyte* %s, int %len) + + ret %RPyString* %rpy +} + +""") + #abs functions extfunctions["%int_abs"] = ((), """ internal fastcc int %int_abs(int %x) { Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Tue Aug 16 12:38:45 2005 @@ -138,13 +138,12 @@ assert f1() == st[1] assert f2() == st[2] -def test_getcwd(): - py.test.skip("ll_os_getcwd not implemented") +def test_os_getcwd(): + cwd = os.getcwd() def does_stuff(): - return os.getcwd() + return os.getcwd() == cwd f1 = compile_function(does_stuff, []) - res = f1() - assert res == os.getcwd() + assert f1() def test_math_frexp(): py.test.skip("ll_math_frexp not implemented") From nik at codespeak.net Tue Aug 16 14:29:52 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 16 Aug 2005 14:29:52 +0200 (CEST) Subject: [pypy-svn] r16099 - pypy/dist/pypy/module/_sre Message-ID: <20050816122952.E8DD027B5F@code1.codespeak.net> Author: nik Date: Tue Aug 16 14:29:52 2005 New Revision: 16099 Modified: pypy/dist/pypy/module/_sre/app_sre.py Log: refactored some methods to be functions. this will allow me to move the _State and _MatchContext classes to interp-level and come up with a scheme to gradually move over the actual bytecode interpreter to interp-level. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Tue Aug 16 14:29:52 2005 @@ -36,7 +36,7 @@ regular expression, return a corresponding MatchObject instance. Return None if the string does not match the pattern.""" state = _State(string, pos, endpos, self.flags) - if state.match(self._code): + if match(state, self._code): return SRE_Match(self, state) else: return None @@ -47,7 +47,7 @@ instance. Return None if no position in the string matches the pattern.""" state = _State(string, pos, endpos, self.flags) - if state.search(self._code): + if search(state, self._code): return SRE_Match(self, state) else: return None @@ -59,7 +59,7 @@ while state.start <= state.end: state.reset() state.string_position = state.start - if not state.search(self._code): + if not search(state, self._code): break match = SRE_Match(self, state) if self.groups == 0 or self.groups == 1: @@ -86,7 +86,7 @@ while not count or n < count: state.reset() state.string_position = state.start - if not state.search(self._code): + if not search(state, self._code): break if last_pos < state.start: sublist.append(string[last_pos:state.start]) @@ -132,7 +132,7 @@ while not maxsplit or n < maxsplit: state.reset() state.string_position = state.start - if not state.search(self._code): + if not search(state, self._code): break if state.start == state.string_position: # zero-width match if last == state.end: # or end of string @@ -176,7 +176,7 @@ state.reset() state.string_position = state.start match = None - if matcher(self.pattern._code): + if matcher(state, self.pattern._code): match = SRE_Match(self.pattern, state) if match is None or state.string_position == state.start: state.start += 1 @@ -185,10 +185,10 @@ return match def match(self): - return self._match_search(self._state.match) + return self._match_search(match) def search(self): - return self._match_search(self._state.search) + return self._match_search(search) class SRE_Match(object): @@ -326,100 +326,6 @@ self.context_stack = [] self.repeat = None - def match(self, pattern_codes): - # Optimization: Check string length. pattern_codes[3] contains the - # minimum length for a string to possibly match. - if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: - if self.end - self.string_position < pattern_codes[3]: - #_log("reject (got %d chars, need %d)" - # % (self.end - self.string_position, pattern_codes[3])) - return False - - dispatcher = _OpcodeDispatcher() - self.context_stack.append(_MatchContext(self, pattern_codes)) - has_matched = None - while len(self.context_stack) > 0: - context = self.context_stack[-1] - has_matched = dispatcher.match(context) - if has_matched is not None: # don't pop if context isn't done - self.context_stack.pop() - return has_matched - - def search(self, pattern_codes): - flags = 0 - if pattern_codes[0] == OPCODES["info"]: - # optimization info block - # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> - if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: - return self.fast_search(pattern_codes) - flags = pattern_codes[2] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] - - string_position = self.start - if pattern_codes[0] == OPCODES["literal"]: - # Special case: Pattern starts with a literal character. This is - # used for short prefixes - character = pattern_codes[1] - while True: - while string_position < self.end \ - and ord(self.string[string_position]) != character: - string_position += 1 - if string_position >= self.end: - return False - self.start = string_position - string_position += 1 - self.string_position = string_position - if flags & SRE_INFO_LITERAL: - return True - if self.match(pattern_codes[2:]): - return True - return False - - # General case - while string_position <= self.end: - self.reset() - self.start = self.string_position = string_position - if self.match(pattern_codes): - return True - string_position += 1 - return False - - def fast_search(self, pattern_codes): - """Skips forward in a string as fast as possible using information from - an optimization info block.""" - # pattern starts with a known prefix - # <5=length> <6=skip> <7=prefix data> - flags = pattern_codes[2] - prefix_len = pattern_codes[5] - prefix_skip = pattern_codes[6] # don't really know what this is good for - prefix = pattern_codes[7:7 + prefix_len] - overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] - i = 0 - string_position = self.string_position - while string_position < self.end: - while True: - if ord(self.string[string_position]) != prefix[i]: - if i == 0: - break - else: - i = overlap[i] - else: - i += 1 - if i == prefix_len: - # found a potential match - self.start = string_position + 1 - prefix_len - self.string_position = string_position + 1 \ - - prefix_len + prefix_skip - if flags & SRE_INFO_LITERAL: - return True # matched all of pure literal pattern - if self.match(pattern_codes[2 * prefix_skip:]): - return True - i = overlap[i] - break - string_position += 1 - return False - def set_mark(self, mark_nr, position): if mark_nr & 1: # This id marks the end of a group. @@ -451,6 +357,103 @@ return _sre.getlower(char_ord, self.flags) +def search(state, pattern_codes): + flags = 0 + if pattern_codes[0] == OPCODES["info"]: + # optimization info block + # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> + #if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: + # return state.fast_search(pattern_codes) + flags = pattern_codes[2] + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + + string_position = state.start + if pattern_codes[0] == OPCODES["literal"]: + # Special case: Pattern starts with a literal character. This is + # used for short prefixes + character = pattern_codes[1] + while True: + while string_position < state.end \ + and ord(state.string[string_position]) != character: + string_position += 1 + if string_position >= state.end: + return False + state.start = string_position + string_position += 1 + state.string_position = string_position + if flags & SRE_INFO_LITERAL: + return True + if match(state, pattern_codes[2:]): + return True + return False + + # General case + while string_position <= state.end: + state.reset() + state.start = state.string_position = string_position + if match(state, pattern_codes): + return True + string_position += 1 + return False + + +def fast_search(state, pattern_codes): + """Skips forward in a string as fast as possible using information from + an optimization info block.""" + # pattern starts with a known prefix + # <5=length> <6=skip> <7=prefix data> + flags = pattern_codes[2] + prefix_len = pattern_codes[5] + prefix_skip = pattern_codes[6] # don't really know what this is good for + prefix = pattern_codes[7:7 + prefix_len] + overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + i = 0 + string_position = state.string_position + while string_position < state.end: + while True: + if ord(state.string[string_position]) != prefix[i]: + if i == 0: + break + else: + i = overlap[i] + else: + i += 1 + if i == prefix_len: + # found a potential match + state.start = string_position + 1 - prefix_len + state.string_position = string_position + 1 \ + - prefix_len + prefix_skip + if flags & SRE_INFO_LITERAL: + return True # matched all of pure literal pattern + if match(state, pattern_codes[2 * prefix_skip:]): + return True + i = overlap[i] + break + string_position += 1 + return False + + +def match(state, pattern_codes): + # Optimization: Check string length. pattern_codes[3] contains the + # minimum length for a string to possibly match. + if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: + if state.end - state.string_position < pattern_codes[3]: + #_log("reject (got %d chars, need %d)" + # % (state.end - state.string_position, pattern_codes[3])) + return False + + dispatcher = _OpcodeDispatcher() + state.context_stack.append(_MatchContext(state, pattern_codes)) + has_matched = None + while len(state.context_stack) > 0: + context = state.context_stack[-1] + has_matched = dispatcher.match(context) + if has_matched is not None: # don't pop if context isn't done + state.context_stack.pop() + return has_matched + + class _MatchContext(object): def __init__(self, state, pattern_codes): From ericvrp at codespeak.net Tue Aug 16 14:43:05 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 16 Aug 2005 14:43:05 +0200 (CEST) Subject: [pypy-svn] r16100 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050816124305.2F66A27B56@code1.codespeak.net> Author: ericvrp Date: Tue Aug 16 14:43:04 2005 New Revision: 16100 Added: pypy/dist/pypy/translator/llvm2/test/test_exc_operation.py (contents, props changed) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: Moved exception raising operations to a seperate test file Added: pypy/dist/pypy/translator/llvm2/test/test_exc_operation.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm2/test/test_exc_operation.py Tue Aug 16 14:43:04 2005 @@ -0,0 +1,160 @@ +import py +import sys +from pypy.translator.llvm2.genllvm import compile_function +from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift + +def test_zerodiv_int(): + def zerodiv_int(n): + try: + r=100/n + except ZeroDivisionError: + return n+7 + return r + f = compile_function(zerodiv_int, [int]) + for i in (-50,0,50): + assert f(i) == zerodiv_int(i) + +def test_zerodiv_uint(): + def zerodiv_uint(n): + try: + r=100/n + except ZeroDivisionError: + return n+7 + return r + f = compile_function(zerodiv_uint, [r_uint]) + for i in (0,50,100): + assert f(i) == zerodiv_uint(i) + +def test_zerodivrem_int(): + def zerodivrem_int(n): + try: + r=100%n + except ZeroDivisionError: + return n+7 + return r + f = compile_function(zerodivrem_int, [int]) + for i in (-50,0,50): + assert f(i) == zerodivrem_int(i) + +def test_zerodivrem_uint(): + def zerodivrem_uint(n): + try: + r=100%n + except ZeroDivisionError: + return n+7 + return r + f = compile_function(zerodivrem_uint, [r_uint]) + for i in (0,50,100): + assert f(i) == zerodivrem_uint(i) + +def test_neg_int_ovf(): + def neg_int_ovf(n): + try: + r=ovfcheck(-n) + except OverflowError: + return 123 + return r + f = compile_function(neg_int_ovf, [int]) + for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): + assert f(i) == neg_int_ovf(i) + +def test_abs_int_ovf(): + def abs_int_ovf(n): + try: + r=ovfcheck(abs(n)) + except OverflowError: + return 123 + return r + f = compile_function(abs_int_ovf, [int]) + for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): + assert f(i) == abs_int_ovf(i) + +from pypy.translator.test import snippet + +def test_int_overflow(): + py.test.skip("int_add_ovf operation missing (raises)") + fn = compile_function(snippet.add_func, [int]) + raises(OverflowError, fn, sys.maxint) + +def test_int_div_ovf_zer(): + py.test.skip("int_floordiv_ovf_zer operation missing (raises)") + fn = compile_function(snippet.div_func, [int]) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_mod_ovf_zer(): + py.test.skip("int_mod_ovf_zer operation missing (raises)") + fn = compile_function(snippet.mod_func, [int]) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_rshift_val(): + py.test.skip("int_rshift_val operation missing (raises)") + fn = compile_function(snippet.rshift_func, [int]) + raises(ValueError, fn, -1) + +def test_int_lshift_ovf_val(): + py.test.skip("int_lshift_ovf_val operation missing (raises)") + fn = compile_function(snippet.lshift_func, [int]) + raises(ValueError, fn, -1) + +def test_uint_arith(): + py.test.skip("uint_floordiv_zer operation missing (raises)") + def fn(i): + try: + return ~(i*(i+1))/(i-1) + except ZeroDivisionError: + return r_uint(91872331) + f = compile_function(fn, [r_uint]) + for value in range(15): + i = r_uint(value) + assert f(i) == fn(i) + +def test_int_add_ovf(): + py.test.skip("int add incorrect overflow test") + def add_func(i): + try: + return ovfcheck(i + 1) + except OverflowError: + return 123 + f = compile_function(add_func, [int]) + assert f(0) == add_func(0) + assert f(0) == 1 + assert f(sys.maxint) == add_func(sys.maxint) + assert f(sys.maxint) == 123 + +def test_int_sub_ovf(): + py.test.skip("ovf test") + def sub_func(i): + try: + return ovfcheck(i - 1) + except OverflowError: + return 123 + f = compile_function(sub_func, [int]) + assert f(0) == sub_func(0) + assert f(0) == 1 + assert f(sys.maxint) == sub_func(sys.maxint) + assert f(sys.maxint) == 123 + +def test_int_div_ovf_zer(): + py.test.skip("ovf test") + f = compile_function(snippet.div_func) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_mod_ovf_zer(): + py.test.skip("ovf test") + f = compile_function(snippet.mod_func) + raises(OverflowError, fn, -1) + raises(ZeroDivisionError, fn, 0) + +def test_int_rshift_val(): + py.test.skip("ovf test") + f = compile_function(snippet.rshift_func) + raises(ValueError, fn, -1) + +def test_int_lshift_ovf_val(): + py.test.skip("ovf test") + f = compile_function(snippet.lshift_func) + raises(ValueError, fn, -1) + raises(OverflowError, fn, 1) Modified: pypy/dist/pypy/translator/llvm2/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_exception.py Tue Aug 16 14:43:04 2005 @@ -94,72 +94,6 @@ assert f( 0) == fn( 0) assert f(10) == fn(10) -def test_zerodiv_int(): - def zerodiv_int(n): - try: - r=100/n - except ZeroDivisionError: - return n+7 - return r - f = compile_function(zerodiv_int, [int]) - for i in (-50,0,50): - assert f(i) == zerodiv_int(i) - -def test_zerodiv_uint(): - def zerodiv_uint(n): - try: - r=100/n - except ZeroDivisionError: - return n+7 - return r - f = compile_function(zerodiv_uint, [r_uint]) - for i in (0,50,100): - assert f(i) == zerodiv_uint(i) - -def test_zerodivrem_int(): - def zerodivrem_int(n): - try: - r=100%n - except ZeroDivisionError: - return n+7 - return r - f = compile_function(zerodivrem_int, [int]) - for i in (-50,0,50): - assert f(i) == zerodivrem_int(i) - -def test_zerodivrem_uint(): - def zerodivrem_uint(n): - try: - r=100%n - except ZeroDivisionError: - return n+7 - return r - f = compile_function(zerodivrem_uint, [r_uint]) - for i in (0,50,100): - assert f(i) == zerodivrem_uint(i) - -def test_neg_int_ovf(): - def neg_int_ovf(n): - try: - r=ovfcheck(-n) - except OverflowError: - return 123 - return r - f = compile_function(neg_int_ovf, [int]) - for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): - assert f(i) == neg_int_ovf(i) - -def test_abs_int_ovf(): - def abs_int_ovf(n): - try: - r=ovfcheck(abs(n)) - except OverflowError: - return 123 - return r - f = compile_function(abs_int_ovf, [int]) - for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): - assert f(i) == abs_int_ovf(i) - def test_reraise1(): def fn(n): lst = range(10) Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Tue Aug 16 14:43:04 2005 @@ -264,56 +264,16 @@ f = compile_function(wrapper, [int]) assert f(42) -def Xtest_float2int(): - """ RTyper is cheating....""" +def test_float2int(): + py.test.skip("RTyper is cheating") def fn(f): return str(f) def wrapper(): res = fn(1.0) return res == "1.0" - - f = compile_function(wrapper, [], view=True) + f = compile_function(wrapper, []) assert f() -def test_int_overflow(): - py.test.skip("int_add_ovf operation missing (raises)") - fn = compile_function(snippet.add_func, [int]) - raises(OverflowError, fn, sys.maxint) - -def test_int_div_ovf_zer(): - py.test.skip("int_floordiv_ovf_zer operation missing (raises)") - fn = compile_function(snippet.div_func, [int]) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) - -def test_int_mod_ovf_zer(): - py.test.skip("int_mod_ovf_zer operation missing (raises)") - fn = compile_function(snippet.mod_func, [int]) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) - -def test_int_rshift_val(): - py.test.skip("int_rshift_val operation missing (raises)") - fn = compile_function(snippet.rshift_func, [int]) - raises(ValueError, fn, -1) - -def test_int_lshift_ovf_val(): - py.test.skip("int_lshift_ovf_val operation missing (raises)") - fn = compile_function(snippet.lshift_func, [int]) - raises(ValueError, fn, -1) - -def test_uint_arith(): - py.test.skip("uint_floordiv_zer operation missing (raises)") - def fn(i): - try: - return ~(i*(i+1))/(i-1) - except ZeroDivisionError: - return r_uint(91872331) - f = compile_function(fn, [r_uint]) - for value in range(15): - i = r_uint(value) - assert f(i) == fn(i) - def test_int_invert(): def fn(i): return ~i @@ -342,55 +302,6 @@ for i in (-25, 0, 75): assert f(i) == int_abs_(i) -def test_int_add_ovf(): - py.test.skip("int add incorrect overflow test") - def add_func(i): - try: - return ovfcheck(i + 1) - except OverflowError: - return 123 - f = compile_function(add_func, [int]) - assert f(0) == add_func(0) - assert f(0) == 1 - assert f(sys.maxint) == add_func(sys.maxint) - assert f(sys.maxint) == 123 - -def test_int_sub_ovf(): - py.test.skip("ovf test") - def sub_func(i): - try: - return ovfcheck(i - 1) - except OverflowError: - return 123 - f = compile_function(sub_func, [int]) - assert f(0) == sub_func(0) - assert f(0) == 1 - assert f(sys.maxint) == sub_func(sys.maxint) - assert f(sys.maxint) == 123 - -def test_int_div_ovf_zer(): - py.test.skip("ovf test") - f = compile_function(snippet.div_func) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) - -def test_int_mod_ovf_zer(): - py.test.skip("ovf test") - f = compile_function(snippet.mod_func) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) - -def test_int_rshift_val(): - py.test.skip("ovf test") - f = compile_function(snippet.rshift_func) - raises(ValueError, fn, -1) - -def test_int_lshift_ovf_val(): - py.test.skip("ovf test") - f = compile_function(snippet.lshift_func) - raises(ValueError, fn, -1) - raises(OverflowError, fn, 1) - def test_float_abs(): def float_abs_(n): return abs(n) From ericvrp at codespeak.net Tue Aug 16 16:20:58 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 16 Aug 2005 16:20:58 +0200 (CEST) Subject: [pypy-svn] r16101 - in pypy/dist/pypy/translator/llvm2: . module tool Message-ID: <20050816142058.EB1F027B56@code1.codespeak.net> Author: ericvrp Date: Tue Aug 16 16:20:57 2005 New Revision: 16101 Added: pypy/dist/pypy/translator/llvm2/module/ll_strtod.py (contents, props changed) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py Log: * proper main(int,char** argv) * moved some functions to ll_strtod.py Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Tue Aug 16 16:20:57 2005 @@ -240,9 +240,27 @@ # XXX we need to create our own main() that calls the actual entry_point function entryfunc_name = t[1].split('(')[0] if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy - codewriter.append("int %main() {") - codewriter.append(" %argv = call fastcc %structtype.list* %ll_newlist__listPtrConst_Signed.2(int 0)") - codewriter.append(" %ret = call fastcc int %entry_point(%structtype.list* %argv)") + codewriter.append("int %main(int% argc, sbyte** %argv) {") + codewriter.append("entry:") + codewriter.append(" %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0)") + codewriter.append(" br label %no_exit") + codewriter.newline() + codewriter.append("no_exit:") + codewriter.append(" %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]") + codewriter.append(" %i.0.0 = cast uint %indvar to int") + codewriter.append(" %tmp.8 = getelementptr sbyte** %argv, uint %indvar") + codewriter.append(" %tmp.9 = load sbyte** %tmp.8") + codewriter.newline() + codewriter.append(" %rpy = call fastcc %RPyString* %string_to_RPyString(sbyte* %tmp.9)") + codewriter.append(" call fastcc void %ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy)") + codewriter.newline() + codewriter.append(" %inc = add int %i.0.0, 1") + codewriter.append(" %tmp.2 = setlt int %inc, %argc") + codewriter.append(" %indvar.next = add uint %indvar, 1") + codewriter.append(" br bool %tmp.2, label %no_exit, label %loopexit") + codewriter.append("loopexit:") + codewriter.newline() + codewriter.append(" %ret = call fastcc int %entry_point(%structtype.list* %pypy_argv)") codewriter.append(" ret int %ret") codewriter.append("}") codewriter.newline() Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Tue Aug 16 16:20:57 2005 @@ -36,9 +36,9 @@ extfunctions = {} #dependencies, llvm-code -import support, ll_os, ll_os_path, ll_time, ll_math +import support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod -for module in (support, ll_os, ll_os_path, ll_time, ll_math): +for module in (support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod): extdeclarations += module.extdeclarations extfunctions.update(module.extfunctions) extdeclarations += '\n;application function prototypes' Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Tue Aug 16 16:20:57 2005 @@ -21,8 +21,6 @@ %__ll_os_lseek = internal constant [12 x sbyte] c"lseek......\\00" %__ll_os_stat = internal constant [12 x sbyte] c"stat.......\\00" %__ll_os_fstat = internal constant [12 x sbyte] c"fstat......\\00" -%__ll_strtod_formatd = internal constant [12 x sbyte] c"formatd....\\00" -%__ll_strtod_parts_to_float = internal constant [12 x sbyte] c"parts2flt..\\00" """ extfunctions = {} @@ -219,17 +217,3 @@ } """) - -extfunctions["%ll_strtod_formatd"] = (("%__debug",), """ -internal fastcc %RPyString* %ll_strtod_formatd(%RPyString* %s, double %x) { - call fastcc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd - ret %RPyString* null -} -""") - -extfunctions["%ll_strtod_parts_to_float"] = (("%__debug",), """ -internal fastcc double %ll_strtod_parts_to_float(%RPyString* s0, %RPyString* s1, %RPyString* s2, %RPyString* s3) { - call fastcc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float - ret double 0.0 -} -""") Added: pypy/dist/pypy/translator/llvm2/module/ll_strtod.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm2/module/ll_strtod.py Tue Aug 16 16:20:57 2005 @@ -0,0 +1,21 @@ +extdeclarations = """ +;ll_strtod.py +%__ll_strtod_formatd = internal constant [12 x sbyte] c"formatd....\\00" +%__ll_strtod_parts_to_float = internal constant [12 x sbyte] c"parts2flt..\\00" +""" + +extfunctions = {} + +extfunctions["%ll_strtod_formatd"] = (("%__debug",), """ +internal fastcc %RPyString* %ll_strtod_formatd(%RPyString* %s, double %x) { + call fastcc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd + ret %RPyString* null +} +""") + +extfunctions["%ll_strtod_parts_to_float"] = (("%__debug",), """ +internal fastcc double %ll_strtod_parts_to_float(%RPyString* s0, %RPyString* s1, %RPyString* s2, %RPyString* s3) { + call fastcc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float + ret double 0.0 +} +""") Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Tue Aug 16 16:20:57 2005 @@ -16,7 +16,7 @@ """) -extfunctions["%cast"] = ((), """ +extfunctions["%cast"] = (("%string_to_RPyString",), """ internal fastcc sbyte* %cast(%RPyString* %structstring) { %source1ptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 %source1 = cast [0 x sbyte]* %source1ptr to sbyte* Modified: pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py (original) +++ pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py Tue Aug 16 16:20:57 2005 @@ -3,12 +3,12 @@ import autopath from sets import Set -from pypy.rpython.module import ll_os, ll_os_path, ll_time, ll_math #XXX keep this list up-to-date +from pypy.rpython.module import ll_os, ll_os_path, ll_time, ll_math, ll_strtod #XXX keep this list up-to-date from pypy.translator.llvm2.module.extfunction import extfunctions def main(): seen = Set() - for module in (ll_os, ll_os_path, ll_time, ll_math): #XXX keep this list up-to-date too + for module in (ll_os, ll_os_path, ll_time, ll_math, ll_strtod): #XXX keep this list up-to-date too suggested_primitives = Set( [func for func in dir(module) if func not in seen and getattr(module.__dict__[func], 'suggested_primitive', False)] ) seen |= suggested_primitives implemented_primitives = Set( [f[1:] for f in extfunctions.keys()] ) From pedronis at codespeak.net Tue Aug 16 22:18:48 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 16 Aug 2005 22:18:48 +0200 (CEST) Subject: [pypy-svn] r16102 - pypy/dist/pypy/translator/c Message-ID: <20050816201848.A739E27B6C@code1.codespeak.net> Author: pedronis Date: Tue Aug 16 22:18:47 2005 New Revision: 16102 Modified: pypy/dist/pypy/translator/c/node.py Log: NULL (pointer) vs NUL char Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Aug 16 22:18:47 2005 @@ -180,7 +180,7 @@ self.LLTYPE = ARRAY original_varlength = varlength if ARRAY is STR.chars: - varlength += 1 # for the NULL char at the end of the string + varlength += 1 # for the NUL char terminator at the end of the string self.varlength = varlength if original_varlength == 1: basename = 'array' From arigo at codespeak.net Tue Aug 16 22:26:16 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 16 Aug 2005 22:26:16 +0200 (CEST) Subject: [pypy-svn] r16103 - pypy/dist/pypy/tool Message-ID: <20050816202616.4E7F927B6C@code1.codespeak.net> Author: arigo Date: Tue Aug 16 22:26:15 2005 New Revision: 16103 Modified: pypy/dist/pypy/tool/tls.py Log: tls.py can provide a complete thread-local object even on top of Python 2.3, because there is a pure Python version of it in 2.4. We can hack and import it from lib-python/2.4.1 and it appears to work nicely on 2.3 as well. Thanks xorAxAx for pointing this out. Modified: pypy/dist/pypy/tool/tls.py ============================================================================== --- pypy/dist/pypy/tool/tls.py (original) +++ pypy/dist/pypy/tool/tls.py Tue Aug 16 22:26:15 2005 @@ -7,5 +7,10 @@ # XXX needs a real object whose attributes are visible only in # the thread that reads/writes them. - class tlsobject(object): - pass + import autopath, os + filename = os.path.join(os.path.dirname(autopath.pypydir), + 'lib-python', '2.4.1', '_threading_local.py') + glob = {'__name__': '_threading_local'} + execfile(filename, glob) + tlsobject = glob['local'] + del glob, filename From rxe at codespeak.net Wed Aug 17 13:08:50 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 17 Aug 2005 13:08:50 +0200 (CEST) Subject: [pypy-svn] r16106 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050817110850.CA87027B58@code1.codespeak.net> Author: rxe Date: Wed Aug 17 13:08:49 2005 New Revision: 16106 Modified: pypy/dist/pypy/translator/llvm2/arraynode.py pypy/dist/pypy/translator/llvm2/structnode.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py pypy/dist/pypy/translator/llvm2/varsize.py Log: Fixes for adding NUL in mallocs when we have a STR.chars Modified: pypy/dist/pypy/translator/llvm2/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm2/arraynode.py Wed Aug 17 13:08:49 2005 @@ -8,7 +8,6 @@ class ArrayTypeNode(LLVMNode): def __init__(self, db, array): assert isinstance(array, lltype.Array) - self.db = db self.array = array arraytype = self.arraytype = array.OF @@ -61,12 +60,12 @@ def writeimpl(self, codewriter): log.writeimpl(self.ref) - fromtype = self.db.repr_type(self.arraytype) varsize.write_constructor(self.db, codewriter, self.ref, self.constructor_decl, - fromtype, + self.array, atomicmalloc=self.is_atomic()) + class VoidArrayTypeNode(LLVMNode): def __init__(self, db, array): Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Wed Aug 17 13:08:49 2005 @@ -77,12 +77,11 @@ name = current._names_without_voids()[-1] current = current._flds[name] assert isinstance(current, lltype.Array) - arraytype = self.db.repr_type(current.OF) varsize.write_constructor(self.db, codewriter, self.ref, self.constructor_decl, - arraytype, + current, indices_to_array, atomicmalloc=self.is_atomic()) Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Wed Aug 17 13:08:49 2005 @@ -192,6 +192,18 @@ os.unlink(tmpfile) assert f() == False +def test_os_path_exists2(): + # forces malloc / versus pbc for NUL testing of C string + tmpfile = str(udir.join('test_os_path_exists.TMP')) + def fn(l): + filename = tmpfile[:l] + return os.path.exists(filename) + f = compile_function(fn, [r_uint], view=True) + open(tmpfile, 'w').close() + lfile = len(tmpfile) + assert f(lfile) == True + assert f(lfile-2) == False + def test_os_path_isdir(): directory = "./." def fn(): Modified: pypy/dist/pypy/translator/llvm2/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/varsize.py (original) +++ pypy/dist/pypy/translator/llvm2/varsize.py Wed Aug 17 13:08:49 2005 @@ -1,3 +1,4 @@ +from pypy.rpython.rstr import STR # example for an array constructor in concrete llvm code: # (thanks to chris lattner) @@ -15,17 +16,26 @@ ret %array* %result }""" -def write_constructor(db, codewriter, ref, constructor_decl, elemtype, +def write_constructor(db, codewriter, ref, constructor_decl, ARRAY, indices_to_array=(), atomicmalloc=False): + #varsized arrays and structs look like this: #Array: {int length , elemtype*} #Struct: {...., Array} # the following indices access the last element in the array + elemtype = db.repr_type(ARRAY.OF) lentype = db.get_machine_word() - elemindices = list(indices_to_array) + [("uint", 1), (lentype, "%len")] - - codewriter.openfunc(constructor_decl) + + codewriter.openfunc(constructor_decl) + + # Need room for NUL terminator + if ARRAY is STR.chars: + codewriter.binaryop("add", "%actuallen", lentype, "%len", 1) + else: + codewriter.cast("%actuallen", lentype, "%len", lentype) + + elemindices = list(indices_to_array) + [("uint", 1), (lentype, "%actuallen")] codewriter.getelementptr("%size", ref + "*", "null", *elemindices) codewriter.cast("%usize", elemtype + "*", "%size", "uint") codewriter.malloc("%ptr", "sbyte", "%usize", atomic=atomicmalloc) @@ -37,6 +47,15 @@ "%result", *indices_to_array) codewriter.store(lentype, "%len", "%arraylength") + + if ARRAY is STR.chars: + # NUL the last element + codewriter.getelementptr("%terminator", + ref + "*", + "%result", + *elemindices) + codewriter.store(elemtype, 0, "%terminator") + codewriter.ret(ref + "*", "%result") codewriter.closefunc() From ericvrp at codespeak.net Wed Aug 17 13:12:18 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 17 Aug 2005 13:12:18 +0200 (CEST) Subject: [pypy-svn] r16107 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050817111218.BB75327B7A@code1.codespeak.net> Author: ericvrp Date: Wed Aug 17 13:12:13 2005 New Revision: 16107 Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py Log: overallocate one byte for all allocation and zero initialize all allocated data (this is a quick fix for non null terminated (dynamic) strings Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Wed Aug 17 13:12:13 2005 @@ -11,14 +11,19 @@ gc_boehm = """declare ccc sbyte* %GC_malloc(uint) declare ccc sbyte* %GC_malloc_atomic(uint) +declare ccc sbyte* %memset(sbyte*, int, uint) internal fastcc sbyte* %gc_malloc(uint %n) { - %ptr = call ccc sbyte* %GC_malloc(uint %n) + %nn = add uint %n, 1 + %ptr = call ccc sbyte* %GC_malloc(uint %nn) + call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %nn) ;XXX force non-zero init for testing ret sbyte* %ptr } internal fastcc sbyte* %gc_malloc_atomic(uint %n) { - %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) + %nn = add uint %n, 1 + %ptr = call ccc sbyte* %GC_malloc_atomic(uint %nn) + call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %nn) ;XXX force non-zero init for testing ret sbyte* %ptr } """ Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Wed Aug 17 13:12:13 2005 @@ -6,7 +6,6 @@ declare ccc int %write(int, sbyte*, int) declare ccc int %read(int, sbyte*, int) declare ccc sbyte* %strncpy(sbyte*, sbyte*, int) -declare ccc int %strlen(sbyte*) declare ccc int %isatty(int) declare ccc int %stat(sbyte*, [32 x int]*) declare ccc int %fstat(int, [32 x int]*) Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Wed Aug 17 13:12:13 2005 @@ -2,6 +2,7 @@ declare ccc double %pow(double, double) declare ccc double %fmod(double, double) declare ccc int %puts(sbyte*) +declare ccc int %strlen(sbyte*) """ From ericvrp at codespeak.net Wed Aug 17 13:24:08 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 17 Aug 2005 13:24:08 +0200 (CEST) Subject: [pypy-svn] r16108 - in pypy/dist/pypy/translator/llvm2: module test Message-ID: <20050817112408.8C97D27B7A@code1.codespeak.net> Author: ericvrp Date: Wed Aug 17 13:24:07 2005 New Revision: 16108 Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: * fixed typos in test/extfunc.py * removed overalocate in malloc, we did that in to places now Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Wed Aug 17 13:24:07 2005 @@ -14,16 +14,14 @@ declare ccc sbyte* %memset(sbyte*, int, uint) internal fastcc sbyte* %gc_malloc(uint %n) { - %nn = add uint %n, 1 - %ptr = call ccc sbyte* %GC_malloc(uint %nn) - call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %nn) ;XXX force non-zero init for testing + %ptr = call ccc sbyte* %GC_malloc(uint %n) + call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) ret sbyte* %ptr } internal fastcc sbyte* %gc_malloc_atomic(uint %n) { - %nn = add uint %n, 1 - %ptr = call ccc sbyte* %GC_malloc_atomic(uint %nn) - call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %nn) ;XXX force non-zero init for testing + %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) + call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) ret sbyte* %ptr } """ Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Wed Aug 17 13:24:07 2005 @@ -6,6 +6,7 @@ from pypy.tool.udir import udir from pypy.translator.llvm2.genllvm import compile_function +from pypy.rpython.rarithmetic import r_uint py.log.setconsumer("genllvm", py.log.STDOUT) py.log.setconsumer("genllvm database prepare", None) @@ -198,7 +199,7 @@ def fn(l): filename = tmpfile[:l] return os.path.exists(filename) - f = compile_function(fn, [r_uint], view=True) + f = compile_function(fn, [r_uint]) open(tmpfile, 'w').close() lfile = len(tmpfile) assert f(lfile) == True From rxe at codespeak.net Wed Aug 17 13:38:53 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 17 Aug 2005 13:38:53 +0200 (CEST) Subject: [pypy-svn] r16109 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050817113853.9442A27B7A@code1.codespeak.net> Author: rxe Date: Wed Aug 17 13:38:52 2005 New Revision: 16109 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py Log: Some tmp changes to speed up compiles. Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Wed Aug 17 13:38:52 2005 @@ -114,6 +114,7 @@ # Run instcombine after redundancy elimination to exploit opportunities # opened up by them "-instcombine", + # propagate conditionals "-condprop", @@ -134,6 +135,21 @@ ])) +# XXX Tmp for debugging +OPTIMIZATION_SWITCHES = (" ".join([ + + # call %malloc -> malloc inst + "-raiseallocs", + + # clean up disgusting code + "-simplifycfg", + + # kill useless allocas + "-mem2reg", + + # clean up disgusting code + "-simplifycfg", ])) + def compile_module(module, source_files, object_files, library_files): open("%s_setup.py" % module, "w").write(str(py.code.Source( @@ -229,4 +245,16 @@ os.chdir(str(lastdir)) if pyxfile: return testmodule - return None + if exe_name: + return exe_name + +if __name__ == "__main__": + + # TMP - Conveinence during debugging + b = "entry_point" + print "opt %s -f %s.bc -o %s_optimized.bc" % (OPTIMIZATION_SWITCHES, b, b) + print "llc %s %s_optimized.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b) + print "as %s.s -o %s.o" % (b, b) + gc_libs = '-lgc -lpthread' + exe_name = "pypy" + print "gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name) From rxe at codespeak.net Wed Aug 17 13:47:32 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 17 Aug 2005 13:47:32 +0200 (CEST) Subject: [pypy-svn] r16110 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050817114732.046A127B6C@code1.codespeak.net> Author: rxe Date: Wed Aug 17 13:47:31 2005 New Revision: 16110 Modified: pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: How NOT to do open source development. Fixes I forget to checkin from yesterday. Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Wed Aug 17 13:47:31 2005 @@ -317,12 +317,20 @@ packed = struct.pack("d", value) repr = "0x" + "".join([("%02x" % ord(ii)) for ii in packed]) return repr + + def char_to_str(self, value): + x = ord(value) + if x >= 128: + r = "cast (ubyte %s to sbyte)" % x + else: + r = str(x) + return r def primitive_to_str(self, type_, value): if type_ is lltype.Bool: repr = str(value).lower() #False --> false elif type_ is lltype.Char: - repr = str(ord(value)) + repr = self.char_to_str(value) elif type_ is lltype.UniChar: repr = str(ord(value)) elif type_ is lltype.Float: Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Wed Aug 17 13:47:31 2005 @@ -37,13 +37,6 @@ 'uint_ge': 'setge', 'uint_gt': 'setgt', - 'char_lt': 'setlt', - 'char_le': 'setle', - 'char_eq': 'seteq', - 'char_ne': 'setne', - 'char_ge': 'setge', - 'char_gt': 'setgt', - 'unichar_lt': 'setlt', 'unichar_le': 'setle', 'unichar_eq': 'seteq', @@ -74,6 +67,14 @@ 'uint_rshift': 'shr', } + + char_operations = {'char_lt': 'setlt', + 'char_le': 'setle', + 'char_eq': 'seteq', + 'char_ne': 'setne', + 'char_ge': 'setge', + 'char_gt': 'setgt'} + def __init__(self, db, codewriter, node, block): self.db = db self.codewriter = codewriter @@ -89,6 +90,8 @@ self.binaryop(op) elif op.opname in self.shift_operations: self.shiftop(op) + elif op.opname in self.char_operations: + self.char_binaryop(op) elif op.opname.startswith('cast_'): if op.opname == 'cast_char_to_int': self.cast_char_to_int(op) @@ -196,6 +199,17 @@ self.db.repr_arg(op.args[0]), self.db.repr_arg(op.args[1])) + def char_binaryop(self, op): + name = self.char_operations[op.opname] + assert len(op.args) == 2 + res = self.db.repr_arg(op.result) + c1 = self.db.repr_tmpvar() + c2 = self.db.repr_tmpvar() + self.codewriter.cast(c1, "sbyte", self.db.repr_arg(op.args[0]), "ubyte") + self.codewriter.cast(c2, "sbyte", self.db.repr_arg(op.args[1]), "ubyte") + self.codewriter.binaryop(name, res, "ubyte", c1, c2) + + def shiftop(self, op): name = self.shift_operations[op.opname] assert len(op.args) == 2 Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Wed Aug 17 13:47:31 2005 @@ -308,3 +308,24 @@ f = compile_function(float_abs_, [float]) for i in (-100.1 -50.2, -0.0, 0.0, 25.3, 50.4): assert f(i) == float_abs_(i) + +def test_cast_to_int(): + def casting(v): + return int(ord(chr(v))) + f = compile_function(casting, [int]) + for ii in range(255): + assert f(ii) == ii + +def test_char_comparisions(): + def comps(v): + x = chr(v) + res = 0 + res += x < chr(0) + res += x > chr(1) + res += x >= chr(127) + res += x < chr(128) + res += x < chr(250) + return res + f = compile_function(comps, [int]) + for ii in range(255): + assert f(ii) == comps(ii) From ericvrp at codespeak.net Wed Aug 17 15:31:16 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 17 Aug 2005 15:31:16 +0200 (CEST) Subject: [pypy-svn] r16112 - in pypy/dist/pypy/translator: . llvm2 Message-ID: <20050817133116.B76D627B7A@code1.codespeak.net> Author: ericvrp Date: Wed Aug 17 15:31:15 2005 New Revision: 16112 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/translator.py Log: * fix to make llvmcompile actually able to compile a standaloe * cleaned up some outcommented code Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Wed Aug 17 15:31:15 2005 @@ -15,10 +15,6 @@ extfunctions, gc_boehm, gc_disabled, dependencies from pypy.translator.llvm2.node import LLVMNode -#XXX commented out because extfuncs temp. not working -#from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod -#from pypy.rpython.annlowlevel import annotate_lowlevel_helper - from pypy.translator.translator import Translator import time @@ -78,25 +74,6 @@ func = self.translator.entrypoint self.entrypoint = func - #XXX commented out because extfuncs temp. not working - # # make sure helper functions are available - # rtyper = self.translator.rtyper - # for ptr in ( - # #rtyper.annotate_helper(ll_math.ll_frexp_result, [lltype.Float, lltype.Signed]), - # #rtyper.annotate_helper(ll_math.ll_modf_result , [lltype.Float, lltype.Float ]), - # rtyper.annotate_helper(ll_os.ll_stat_result , [lltype.Signed] * 10), - # ): - # c = inputconst(lltype.typeOf(ptr), ptr) - # self.db.prepare_arg_value(c) - - # make sure exception matching and exception type are available - # XXX Comment out anywat - #e = self.translator.rtyper.getexceptiondata() - #for ll_helper in (e.ll_exception_match, e.ll_raise_OSError): - # ptr = getfunctionptr(self.translator, ll_helper) - # c = inputconst(lltype.typeOf(ptr), ptr) - # self.db.prepare_arg_value(c) - ptr = getfunctionptr(self.translator, func) c = inputconst(lltype.typeOf(ptr), ptr) entry_point = c.value._obj @@ -273,7 +250,7 @@ filename, really_compile=True, standalone=False, - optimize=False, #XXX disabled because it breaks things (debug output) + optimize=True, exe_name=None): if not llvm_is_on_path(): Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Wed Aug 17 15:31:15 2005 @@ -283,22 +283,12 @@ from pypy.translator.llvm2 import genllvm if self.annotator is None: raise ValueError, "function has to be annotated." + if standalone: + exe_name = self.entrypoint.__name__ + else: + exe_name = None self.frozen = True - return genllvm.genllvm(self, really_compile=really_compile, standalone=standalone, optimize=optimize) - - #self.frozen = True - #if standalone: - # builder = genllvm.LLVMStandaloneBuilder(self, optimize=optimize) - #else: - # builder = genllvm.LLVMExtModuleBuilder(self, optimize=optimize) - #source_filename = builder.generate_source() - #if not really_compile: - # return source_filename - #builder.compile() - #if standalone: - # return builder.executable_name - #builder.import_module() - #return builder.get_entry_point() + return genllvm.genllvm(self, really_compile=really_compile, standalone=standalone, optimize=optimize, exe_name=exe_name) def call(self, *args): """Calls underlying Python function.""" From rxe at codespeak.net Wed Aug 17 16:08:58 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 17 Aug 2005 16:08:58 +0200 (CEST) Subject: [pypy-svn] r16113 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050817140858.B792827B7A@code1.codespeak.net> Author: rxe Date: Wed Aug 17 16:08:57 2005 New Revision: 16113 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: typo Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Wed Aug 17 16:08:57 2005 @@ -217,7 +217,7 @@ # XXX we need to create our own main() that calls the actual entry_point function entryfunc_name = t[1].split('(')[0] if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy - codewriter.append("int %main(int% argc, sbyte** %argv) {") + codewriter.append("int %main(int %argc, sbyte** %argv) {") codewriter.append("entry:") codewriter.append(" %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0)") codewriter.append(" br label %no_exit") From rxe at codespeak.net Wed Aug 17 17:00:46 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 17 Aug 2005 17:00:46 +0200 (CEST) Subject: [pypy-svn] r16114 - in pypy/dist/pypy/translator/llvm2: . test Message-ID: <20050817150046.0D37127B6C@code1.codespeak.net> Author: rxe Date: Wed Aug 17 17:00:44 2005 New Revision: 16114 Modified: pypy/dist/pypy/translator/llvm2/database.py pypy/dist/pypy/translator/llvm2/test/test_lltype.py Log: Fix up floating point number representation issues (thanks mwh) Modified: pypy/dist/pypy/translator/llvm2/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/database.py (original) +++ pypy/dist/pypy/translator/llvm2/database.py Wed Aug 17 17:00:44 2005 @@ -314,7 +314,10 @@ elif repr in ["inf", "nan"]: # Need hex repr import struct - packed = struct.pack("d", value) + packed = struct.pack("d", value) + if sys.byteorder == 'little': + packed = packed[::-1] + repr = "0x" + "".join([("%02x" % ord(ii)) for ii in packed]) return repr Modified: pypy/dist/pypy/translator/llvm2/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_lltype.py Wed Aug 17 17:00:44 2005 @@ -227,16 +227,14 @@ floats.f1 = 1.25 floats.f2 = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.252984 floats.f3 = float(29050000000000000000000000000000000000000000000000000000000000000000) - floats.f4 = float("inf") - floats.f5 = float("nan") - f = float("nan") + floats.f4 = 1e300 * 1e300 + nan = floats.f5 = floats.f4/floats.f4 def floats_fn(): res = floats.f1 == 1.25 res += floats.f2 > 1e100 - res += floats.f3 > 1e50 - # XXX Need to find out more about these in llvm - #res += floats.f4 > 1e200 - #res += floats.f5 == f + res += floats.f3 > 1e50 + res += floats.f4 > 1e200 + res += floats.f5 == nan return res f = compile_function(floats_fn, []) From ale at codespeak.net Wed Aug 17 19:25:20 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 17 Aug 2005 19:25:20 +0200 (CEST) Subject: [pypy-svn] r16116 - in pypy/dist/pypy/module/_codecs: . test Message-ID: <20050817172520.4A28427B7C@code1.codespeak.net> Author: ale Date: Wed Aug 17 19:25:19 2005 New Revision: 16116 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: added missing implementation of escape_decode and a test still missing named unicode character Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Wed Aug 17 19:25:19 2005 @@ -284,7 +284,56 @@ def escape_decode(data,errors='strict'): """None """ - return data,len(data) + l = len(data) + i = 0 + res = [] + while i Author: ericvrp Date: Wed Aug 17 23:50:55 2005 New Revision: 16120 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py Log: * fixed bug with calling convention mismatch (found by Chris Lattner) * using another set of optimization options, suggested by Chris Lattner. Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Wed Aug 17 23:50:55 2005 @@ -132,9 +132,9 @@ # merge dup global constants "-constmerge", - ])) + # XXX Tmp for debugging OPTIMIZATION_SWITCHES = (" ".join([ @@ -148,9 +148,15 @@ "-mem2reg", # clean up disgusting code - "-simplifycfg", ])) + "-simplifycfg", + ])) +# suggested by: gccas /dev/null -o /dev/null -debug-pass=Arguments +OPTIMIZATION_SWITCHES = (" ".join([ + "-verify -lowersetjmp -funcresolve -raiseallocs -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -raise -tailduplicate -simplifycfg -scalarrepl -instcombine -break-crit-edges -condprop -tailcallelim -simplifycfg -reassociate -loopsimplify -licm -instcombine -indvars -loop-unroll -instcombine -load-vn -gcse -sccp -instcombine -break-crit-edges -condprop -dse -mergereturn -adce -simplifycfg -deadtypeelim -constmerge -verify" + ])) + def compile_module(module, source_files, object_files, library_files): open("%s_setup.py" % module, "w").write(str(py.code.Source( ''' Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Wed Aug 17 23:50:55 2005 @@ -15,6 +15,9 @@ %errno = external global int +%__print_debug_info = internal global bool false +%__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" + %__ll_os_getcwd = internal constant [12 x sbyte] c"getcwd.....\\00" %__ll_os_ftruncate = internal constant [12 x sbyte] c"ftruncate..\\00" %__ll_os_lseek = internal constant [12 x sbyte] c"lseek......\\00" Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Wed Aug 17 23:50:55 2005 @@ -3,13 +3,21 @@ declare ccc double %fmod(double, double) declare ccc int %puts(sbyte*) declare ccc int %strlen(sbyte*) +declare ccc int %strcmp(sbyte*, sbyte*) """ extfunctions = {} extfunctions["%__debug"] = ((), """ -void %__debug([12 x sbyte]* %msg12) { +internal fastcc void %__debug([12 x sbyte]* %msg12) { + %cond = load bool* %__print_debug_info + br bool %__print_debug_info, label %print_it, label %do_nothing + +do_nothing: + ret void + +print_it: %msg = getelementptr [12 x sbyte]* %msg12, long 0, long 0 call int %puts(sbyte* %msg) ret void From pedronis at codespeak.net Thu Aug 18 00:25:55 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 18 Aug 2005 00:25:55 +0200 (CEST) Subject: [pypy-svn] r16122 - pypy/extradoc/sprintinfo Message-ID: <20050817222555.1479D27B80@code1.codespeak.net> Author: pedronis Date: Thu Aug 18 00:25:54 2005 New Revision: 16122 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: updated with Strakt's people fresher info Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 18 00:25:54 2005 @@ -12,7 +12,7 @@ Name Arrive/Depart Accomodation =================== ============== ===================== Armin Rigo 21st-29th Aug ? -Samuele Pedroni ?21st-29th Aug ? +Samuele Pedroni 20st-30th Aug Hotel Ibis Carl Friedrich Bolz 21st-29th Aug ? Niklaus Haldimann 21st-29th Aug private Eric van Riet Paap 22nd-28th Aug private @@ -20,10 +20,10 @@ Richard Emslie 22nd-29th Aug private Michael Hudson (?) ? ? Beatrice Duering 21st-30th Aug Hotel Ibis -Jacob Hallen ? ? -Laura Creighton ? ? +Jacob Hallen 20st-30th Aug Hotel Ibis +Laura Creighton 20st-30th Aug Hotel Ibis Ludovic Aubry ? ? -Anders Chrigstroem ? ? +Anders Chrigstroem 20st-30th Aug Hotel Ibis Christian Tismer ? ? Anders Lehmann 21st-29th Aug =================== ============== ===================== From tismer at codespeak.net Thu Aug 18 01:31:48 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 18 Aug 2005 01:31:48 +0200 (CEST) Subject: [pypy-svn] r16124 - pypy/extradoc/sprintinfo Message-ID: <20050817233148.D42D127B7C@code1.codespeak.net> Author: tismer Date: Thu Aug 18 01:31:47 2005 New Revision: 16124 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: my travel info Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 18 01:31:47 2005 @@ -24,6 +24,6 @@ Laura Creighton 20st-30th Aug Hotel Ibis Ludovic Aubry ? ? Anders Chrigstroem 20st-30th Aug Hotel Ibis -Christian Tismer ? ? +Christian Tismer 21st-27th Aug Hotel Ibis Anders Lehmann 21st-29th Aug =================== ============== ===================== From ericvrp at codespeak.net Thu Aug 18 10:52:54 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 18 Aug 2005 10:52:54 +0200 (CEST) Subject: [pypy-svn] r16127 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050818085254.3477D27B83@code1.codespeak.net> Author: ericvrp Date: Thu Aug 18 10:52:53 2005 New Revision: 16127 Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/varsize.py Log: Fixed: string null terminator was written one byte to far. Modified: no longer clear all malloced data, let's see if that works. Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 18 10:52:53 2005 @@ -11,17 +11,20 @@ gc_boehm = """declare ccc sbyte* %GC_malloc(uint) declare ccc sbyte* %GC_malloc_atomic(uint) -declare ccc sbyte* %memset(sbyte*, int, uint) + +;XXX now trying to set only null terminator of varsize array for chars! +; might need to clear the hash value of rpystrings too. +;declare ccc sbyte* %memset(sbyte*, int, uint) internal fastcc sbyte* %gc_malloc(uint %n) { %ptr = call ccc sbyte* %GC_malloc(uint %n) - call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) + ;call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) ret sbyte* %ptr } internal fastcc sbyte* %gc_malloc_atomic(uint %n) { %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) - call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) + ;call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) ret sbyte* %ptr } """ Modified: pypy/dist/pypy/translator/llvm2/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/varsize.py (original) +++ pypy/dist/pypy/translator/llvm2/varsize.py Thu Aug 18 10:52:53 2005 @@ -41,19 +41,20 @@ codewriter.malloc("%ptr", "sbyte", "%usize", atomic=atomicmalloc) codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") - indices_to_array = tuple(indices_to_array) + (("uint", 0),) + indices_to_arraylength = tuple(indices_to_array) + (("uint", 0),) # the following accesses the length field of the array codewriter.getelementptr("%arraylength", ref + "*", "%result", - *indices_to_array) + *indices_to_arraylength) codewriter.store(lentype, "%len", "%arraylength") if ARRAY is STR.chars: # NUL the last element + lastelemindices = list(indices_to_array) + [("uint", 1), (lentype, "%len")] codewriter.getelementptr("%terminator", ref + "*", "%result", - *elemindices) + *lastelemindices) codewriter.store(elemtype, 0, "%terminator") codewriter.ret(ref + "*", "%result") From ericvrp at codespeak.net Thu Aug 18 10:54:51 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 18 Aug 2005 10:54:51 +0200 (CEST) Subject: [pypy-svn] r16128 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050818085451.B4E1927B83@code1.codespeak.net> Author: ericvrp Date: Thu Aug 18 10:54:50 2005 New Revision: 16128 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: refactoring: moving %main(..) out of genllvm.py Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 18 10:54:50 2005 @@ -168,24 +168,6 @@ for typ_decl in self.db.getnodes(): typ_decl.writeimpl(codewriter) - if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() - depdone = {} - for funcname,value in extfuncnode.ExternalFuncNode.used_external_functions.iteritems(): - deps = dependencies(funcname,[]) - deps.reverse() - for dep in deps: - if dep not in depdone: - try: - llvm_code = extfunctions[dep][1] - except KeyError: - msg = 'primitive function %s has no implementation' % dep - codewriter.comment('XXX: Error: ' + msg) - #raise Exception('primitive function %s has no implementation' %(dep,)) - continue - for extfunc in llvm_code.split('\n'): - codewriter.append(extfunc) - depdone[dep] = True - if self.debug: print 'gen_llvm_source entrypoint) ' + time.ctime() #XXX use codewriter methods here decl = self.entrynode.getdecl() @@ -217,30 +199,25 @@ # XXX we need to create our own main() that calls the actual entry_point function entryfunc_name = t[1].split('(')[0] if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy - codewriter.append("int %main(int %argc, sbyte** %argv) {") - codewriter.append("entry:") - codewriter.append(" %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0)") - codewriter.append(" br label %no_exit") - codewriter.newline() - codewriter.append("no_exit:") - codewriter.append(" %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ]") - codewriter.append(" %i.0.0 = cast uint %indvar to int") - codewriter.append(" %tmp.8 = getelementptr sbyte** %argv, uint %indvar") - codewriter.append(" %tmp.9 = load sbyte** %tmp.8") - codewriter.newline() - codewriter.append(" %rpy = call fastcc %RPyString* %string_to_RPyString(sbyte* %tmp.9)") - codewriter.append(" call fastcc void %ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy)") - codewriter.newline() - codewriter.append(" %inc = add int %i.0.0, 1") - codewriter.append(" %tmp.2 = setlt int %inc, %argc") - codewriter.append(" %indvar.next = add uint %indvar, 1") - codewriter.append(" br bool %tmp.2, label %no_exit, label %loopexit") - codewriter.append("loopexit:") - codewriter.newline() - codewriter.append(" %ret = call fastcc int %entry_point(%structtype.list* %pypy_argv)") - codewriter.append(" ret int %ret") - codewriter.append("}") - codewriter.newline() + extfuncnode.ExternalFuncNode.used_external_functions['%main'] = True + + if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() + depdone = {} + for funcname,value in extfuncnode.ExternalFuncNode.used_external_functions.iteritems(): + deps = dependencies(funcname,[]) + deps.reverse() + for dep in deps: + if dep not in depdone: + try: + llvm_code = extfunctions[dep][1] + except KeyError: + msg = 'primitive function %s has no implementation' % dep + codewriter.comment('XXX: Error: ' + msg) + #raise Exception('primitive function %s has no implementation' %(dep,)) + continue + for extfunc in llvm_code.split('\n'): + codewriter.append(extfunc) + depdone[dep] = True comment("End of file") ; nl() if self.debug: print 'gen_llvm_source return) ' + time.ctime() Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Thu Aug 18 10:54:50 2005 @@ -15,9 +15,6 @@ %errno = external global int -%__print_debug_info = internal global bool false -%__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" - %__ll_os_getcwd = internal constant [12 x sbyte] c"getcwd.....\\00" %__ll_os_ftruncate = internal constant [12 x sbyte] c"ftruncate..\\00" %__ll_os_lseek = internal constant [12 x sbyte] c"lseek......\\00" Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 18 10:54:50 2005 @@ -4,6 +4,9 @@ declare ccc int %puts(sbyte*) declare ccc int %strlen(sbyte*) declare ccc int %strcmp(sbyte*, sbyte*) + +%__print_debug_info = internal global bool false +%__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" """ @@ -12,13 +15,13 @@ extfunctions["%__debug"] = ((), """ internal fastcc void %__debug([12 x sbyte]* %msg12) { %cond = load bool* %__print_debug_info - br bool %__print_debug_info, label %print_it, label %do_nothing + br bool %cond, label %print_it, label %do_nothing do_nothing: ret void print_it: - %msg = getelementptr [12 x sbyte]* %msg12, long 0, long 0 + %msg = getelementptr [12 x sbyte]* %msg12, int 0, int 0 call int %puts(sbyte* %msg) ret void } @@ -234,3 +237,42 @@ ret int %%t } """ % locals()) + +extfunctions["%main"] = (("%string_to_RPyString"), """ +int %main(int %argc, sbyte** %argv) { +entry: + %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0) + br label %no_exit + +no_exit: + %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] + %i.0.0 = cast uint %indvar to int + %tmp.8 = getelementptr sbyte** %argv, uint %indvar + %tmp.9 = load sbyte** %tmp.8 + + %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 + %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) + %cond = seteq int %res, 0 + br bool %cond, label %debugging, label %not_debugging + +debugging: + store bool true, bool* %__print_debug_info + br label %next_arg + +not_debugging: + %rpy = call fastcc %RPyString* %string_to_RPyString(sbyte* %tmp.9) + call fastcc void %ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) + br label %next_arg + +next_arg: + %inc = add int %i.0.0, 1 + %tmp.2 = setlt int %inc, %argc + %indvar.next = add uint %indvar, 1 + br bool %tmp.2, label %no_exit, label %loopexit + +loopexit: + + %ret = call fastcc int %entry_point(%structtype.list* %pypy_argv) + ret int %ret +} +""") Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Thu Aug 18 10:54:50 2005 @@ -193,7 +193,7 @@ os.unlink(tmpfile) assert f() == False -def test_os_path_exists2(): +def test_dynamic_string_null_termination(): # forces malloc / versus pbc for NUL testing of C string tmpfile = str(udir.join('test_os_path_exists.TMP')) def fn(l): From arigo at codespeak.net Thu Aug 18 11:52:13 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Aug 2005 11:52:13 +0200 (CEST) Subject: [pypy-svn] r16129 - pypy/extradoc/sprintinfo Message-ID: <20050818095213.B128A27B80@code1.codespeak.net> Author: arigo Date: Thu Aug 18 11:52:13 2005 New Revision: 16129 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: My sprint info. Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 18 11:52:13 2005 @@ -11,7 +11,7 @@ =================== ============== ===================== Name Arrive/Depart Accomodation =================== ============== ===================== -Armin Rigo 21st-29th Aug ? +Armin Rigo 21st-30th Aug Hotel Ibis Samuele Pedroni 20st-30th Aug Hotel Ibis Carl Friedrich Bolz 21st-29th Aug ? Niklaus Haldimann 21st-29th Aug private From cfbolz at codespeak.net Thu Aug 18 12:12:03 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 18 Aug 2005 12:12:03 +0200 (CEST) Subject: [pypy-svn] r16130 - pypy/extradoc/sprintinfo Message-ID: <20050818101203.1EDF227B7A@code1.codespeak.net> Author: cfbolz Date: Thu Aug 18 12:12:02 2005 New Revision: 16130 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: some more sprint info: Michael won't make it :-( I obviously am privately accomodated :-) Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 18 12:12:02 2005 @@ -13,12 +13,11 @@ =================== ============== ===================== Armin Rigo 21st-30th Aug Hotel Ibis Samuele Pedroni 20st-30th Aug Hotel Ibis -Carl Friedrich Bolz 21st-29th Aug ? +Carl Friedrich Bolz 21st-29th Aug private Niklaus Haldimann 21st-29th Aug private Eric van Riet Paap 22nd-28th Aug private Holger Krekel 21st-28th Aug private Richard Emslie 22nd-29th Aug private -Michael Hudson (?) ? ? Beatrice Duering 21st-30th Aug Hotel Ibis Jacob Hallen 20st-30th Aug Hotel Ibis Laura Creighton 20st-30th Aug Hotel Ibis From ale at codespeak.net Thu Aug 18 12:48:36 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 18 Aug 2005 12:48:36 +0200 (CEST) Subject: [pypy-svn] r16131 - pypy/extradoc/sprintinfo Message-ID: <20050818104836.6379F27B8C@code1.codespeak.net> Author: ale Date: Thu Aug 18 12:48:35 2005 New Revision: 16131 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: updated info Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 18 12:48:35 2005 @@ -24,5 +24,5 @@ Ludovic Aubry ? ? Anders Chrigstroem 20st-30th Aug Hotel Ibis Christian Tismer 21st-27th Aug Hotel Ibis -Anders Lehmann 21st-29th Aug +Anders Lehmann 22st-29th Aug Hotel Ibis =================== ============== ===================== From arigo at codespeak.net Thu Aug 18 13:40:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Aug 2005 13:40:46 +0200 (CEST) Subject: [pypy-svn] r16132 - pypy/dist/pypy/module/_codecs/test Message-ID: <20050818114046.1233327B8A@code1.codespeak.net> Author: arigo Date: Thu Aug 18 13:40:46 2005 New Revision: 16132 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: Test for some open bugs in the string_escape codec. Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Thu Aug 18 13:40:46 2005 @@ -42,4 +42,8 @@ def test_escape_decode(self): test = 'a\n\\b\x00c\td\u2045'.encode('string_escape') - assert test.decode('string_escape') =='a\n\\b\x00c\td\u2045' \ No newline at end of file + assert test.decode('string_escape') =='a\n\\b\x00c\td\u2045' + skip("string_escape has open bugs") + assert '\\077'.decode('string_escape') == '?' + assert '\\u1234'.decode('string_escape') == '\u1234' + assert '\\x41u1234'.decode('string_escape') == 'Au1234' From ludal at codespeak.net Thu Aug 18 14:03:47 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 18 Aug 2005 14:03:47 +0200 (CEST) Subject: [pypy-svn] r16133 - pypy/extradoc/sprintinfo Message-ID: <20050818120347.1CA0227B8A@code1.codespeak.net> Author: ludal Date: Thu Aug 18 14:03:45 2005 New Revision: 16133 Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt Log: updated info Modified: pypy/extradoc/sprintinfo/heidelberg-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-people.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-people.txt Thu Aug 18 14:03:45 2005 @@ -21,7 +21,7 @@ Beatrice Duering 21st-30th Aug Hotel Ibis Jacob Hallen 20st-30th Aug Hotel Ibis Laura Creighton 20st-30th Aug Hotel Ibis -Ludovic Aubry ? ? +Ludovic Aubry 21st-28th Aug Hotel Ibis Anders Chrigstroem 20st-30th Aug Hotel Ibis Christian Tismer 21st-27th Aug Hotel Ibis Anders Lehmann 22st-29th Aug Hotel Ibis From ericvrp at codespeak.net Thu Aug 18 14:38:39 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 18 Aug 2005 14:38:39 +0200 (CEST) Subject: [pypy-svn] r16134 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050818123839.46A3E27B8A@code1.codespeak.net> Author: ericvrp Date: Thu Aug 18 14:38:38 2005 New Revision: 16134 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/varsize.py Log: * added optional cconv to codewriter calls and invokes * attempt to do less zero-initialization after mallocs, by only initing array of chars. * attempt to speed up llvm compilation and getting rid of the ..._optimized.bc file Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Thu Aug 18 14:38:38 2005 @@ -191,28 +191,21 @@ library_files.append('gc') else: gc_libs = '' - + + if optimize: + cmds = ["llvm-as < %s.ll | opt %s > %s.bc" % (b, OPTIMIZATION_SWITCHES, b)] + else: + cmds = ["llvm-as < %s.ll > %s.bc" % (b, b)] + if sys.maxint == 2147483647: #32 bit platform - if optimize: - cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), - "opt %s -f %s.bc -o %s_optimized.bc" % (OPTIMIZATION_SWITCHES, b, b), - "llc %s %s_optimized.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] - else: - cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), - "llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)] + cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) if exe_name: cmds.append("gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) object_files.append("%s.o" % b) else: #assume 64 bit platform (x86-64?) #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! - if optimize: - cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), - "opt %s -f %s.bc -o %s_optimized.bc" % (OPTIMIZATION_SWITCHES, b, b), - "llc %s %s_optimized.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)] - else: - cmds = ["llvm-as %s.ll -f -o %s.bc" % (b, b), - "llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)] + cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)) source_files.append("%s.c" % b) try: Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Thu Aug 18 14:38:38 2005 @@ -46,8 +46,8 @@ self.append("%s = type %s (%s)" % (name, rettyperepr, ", ".join(argtypereprs))) - def declare(self, decl): - self.append("declare fastcc %s" %(decl,)) + def declare(self, decl, cconv='fastcc'): + self.append("declare %s %s" %(cconv, decl,)) def startimpl(self): self.newline() @@ -68,14 +68,14 @@ self.indent("switch %s %s, label %%%s [%s ]" % (intty, cond, defaultdest, labels)) - def openfunc(self, decl, is_entrynode=False): + def openfunc(self, decl, is_entrynode=False, cconv='fastcc'): self.malloc_count = count(0).next self.newline() if is_entrynode: linkage_type = '' else: linkage_type = 'internal ' - self.append("%sfastcc %s {" % (linkage_type, decl,)) + self.append("%s%s %s {" % (linkage_type, cconv, decl,)) def closefunc(self): self.append("}") @@ -104,29 +104,29 @@ def shiftop(self, name, targetvar, type_, ref1, ref2): self.indent("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) - def call(self, targetvar, returntype, functionref, argrefs, argtypes): + def call(self, targetvar, returntype, functionref, argrefs, argtypes, cconv='fastcc'): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("%s = call fastcc %s %s(%s)" % (targetvar, returntype, functionref, + self.indent("%s = call %s %s %s(%s)" % (targetvar, cconv, returntype, functionref, ", ".join(arglist))) - def call_void(self, functionref, argrefs, argtypes): + def call_void(self, functionref, argrefs, argtypes, cconv='fastcc'): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("call fastcc void %s(%s)" % (functionref, ", ".join(arglist))) + self.indent("call %s void %s(%s)" % (cconv, functionref, ", ".join(arglist))) - def invoke(self, targetvar, returntype, functionref, argrefs, argtypes, label, except_label): + def invoke(self, targetvar, returntype, functionref, argrefs, argtypes, label, except_label, cconv='fastcc'): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("%s = invoke fastcc %s %s(%s) to label %%%s except label %%%s" % (targetvar, returntype, functionref, + self.indent("%s = invoke %s %s %s(%s) to label %%%s except label %%%s" % (targetvar, cconv, returntype, functionref, ", ".join(arglist), label, except_label)) - def invoke_void(self, functionref, argrefs, argtypes, label, except_label): + def invoke_void(self, functionref, argrefs, argtypes, label, except_label, cconv='fastcc'): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("invoke fastcc void %s(%s) to label %%%s except label %%%s" % (functionref, ", ".join(arglist), label, except_label)) + self.indent("invoke %s void %s(%s) to label %%%s except label %%%s" % (cconv, functionref, ", ".join(arglist), label, except_label)) def cast(self, targetvar, fromtype, fromvar, targettype): self.indent("%(targetvar)s = cast %(fromtype)s " "%(fromvar)s to %(targettype)s" % locals()) - def malloc(self, targetvar, type_, size=1, atomic=False): + def malloc(self, targetvar, type_, size=1, atomic=False, cconv='fastcc'): n = self.malloc_count() if n: cnt = ".%d" % n @@ -135,7 +135,7 @@ postfix = ('', '_atomic')[atomic] self.indent("%%malloc.Size%(cnt)s = getelementptr %(type_)s* null, uint %(size)s" % locals()) self.indent("%%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to uint" % locals()) - self.indent("%%malloc.Ptr%(cnt)s = call fastcc sbyte* %%gc_malloc%(postfix)s(uint %%malloc.SizeU%(cnt)s)" % locals()) + self.indent("%%malloc.Ptr%(cnt)s = call %(cconv)s sbyte* %%gc_malloc%(postfix)s(uint %%malloc.SizeU%(cnt)s)" % locals()) self.indent("%(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s*" % locals()) def getelementptr(self, targetvar, type, typevar, *indices): Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 18 14:38:38 2005 @@ -14,7 +14,7 @@ ;XXX now trying to set only null terminator of varsize array for chars! ; might need to clear the hash value of rpystrings too. -;declare ccc sbyte* %memset(sbyte*, int, uint) +declare ccc sbyte* %memset(sbyte*, int, uint) internal fastcc sbyte* %gc_malloc(uint %n) { %ptr = call ccc sbyte* %GC_malloc(uint %n) Modified: pypy/dist/pypy/translator/llvm2/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/varsize.py (original) +++ pypy/dist/pypy/translator/llvm2/varsize.py Thu Aug 18 14:38:38 2005 @@ -40,6 +40,9 @@ codewriter.cast("%usize", elemtype + "*", "%size", "uint") codewriter.malloc("%ptr", "sbyte", "%usize", atomic=atomicmalloc) codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") + + if ARRAY is STR.chars: + codewriter.call('%memset_result', 'sbyte*', '%memset', ['%ptr', '0', '%usize',], ['sbyte*', 'int', 'uint'], cconv='ccc') indices_to_arraylength = tuple(indices_to_array) + (("uint", 0),) # the following accesses the length field of the array @@ -47,15 +50,15 @@ "%result", *indices_to_arraylength) codewriter.store(lentype, "%len", "%arraylength") - - if ARRAY is STR.chars: - # NUL the last element - lastelemindices = list(indices_to_array) + [("uint", 1), (lentype, "%len")] - codewriter.getelementptr("%terminator", - ref + "*", - "%result", - *lastelemindices) - codewriter.store(elemtype, 0, "%terminator") + + #if ARRAY is STR.chars: #(temp. disabled because we are moving memset from gc_malloc to here) + # # NUL the last element + # #lastelemindices = list(indices_to_array) + [("uint", 1), (lentype, "%len")] + # #codewriter.getelementptr("%terminator", + # # ref + "*", + # # "%result", + # # *lastelemindices) + # #codewriter.store(elemtype, 0, "%terminator") codewriter.ret(ref + "*", "%result") codewriter.closefunc() From ale at codespeak.net Thu Aug 18 15:00:04 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 18 Aug 2005 15:00:04 +0200 (CEST) Subject: [pypy-svn] r16135 - in pypy/dist/pypy/module/_codecs: . test Message-ID: <20050818130004.BE28A27B8A@code1.codespeak.net> Author: ale Date: Thu Aug 18 15:00:03 2005 New Revision: 16135 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: corrected some bugs (Thanks Armin) Enabled the tests Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Thu Aug 18 15:00:03 2005 @@ -312,20 +312,18 @@ if data[i] == 'v': res += '\v' if data[i] == '0': - octal = data[i+1:i+2] + octal = data[i+1:i+3] res += chr(int(octal,8)) i += 2 if data[i] == 'x': - hexa = data[i+1:i+2] + hexa = data[i+1:i+3] res += chr(int(hexa,16)) i += 2 if data[i] == 'u': - hexa = data[i+1:i+4] - res += unichr(int(hexa,16)) + res += data[i-1:i+5] i += 4 if data[i] == 'U': - hexa = data[i+1:i+8] - res += unichr(int(hexa,16)) + res += data[i-1:i+9] i += 8 if data[i] == 'N': raise NotImplementedError Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Thu Aug 18 15:00:03 2005 @@ -43,7 +43,7 @@ def test_escape_decode(self): test = 'a\n\\b\x00c\td\u2045'.encode('string_escape') assert test.decode('string_escape') =='a\n\\b\x00c\td\u2045' - skip("string_escape has open bugs") + # skip("string_escape has open bugs") assert '\\077'.decode('string_escape') == '?' assert '\\u1234'.decode('string_escape') == '\u1234' assert '\\x41u1234'.decode('string_escape') == 'Au1234' From pedronis at codespeak.net Thu Aug 18 15:28:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 18 Aug 2005 15:28:13 +0200 (CEST) Subject: [pypy-svn] r16136 - pypy/extradoc/sprintinfo Message-ID: <20050818132813.982FD27B8A@code1.codespeak.net> Author: pedronis Date: Thu Aug 18 15:28:12 2005 New Revision: 16136 Added: pypy/extradoc/sprintinfo/heidelberg-planning.txt (contents, props changed) Log: first draft of heidelberg planning Added: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Thu Aug 18 15:28:12 2005 @@ -0,0 +1,65 @@ + +PyPy Heidelberg sprint planning (22th-29st August) +----------------------------------------------------- + +* Translation + + - Finish(?) GIL-based threading + + - (Decide whether to try to implement other threading locking policies) + + - Isolate refcounting in genc, and + have an option to enable and use Boehm instead + +* 2.4.1 Compliance + + - Fix/adjust/prioritize compliance test problems + - Do we want to try to pass test_unicode(/test_codecs) ? + - Some other "non-core" tests revealing real bugs/problems? + +* Compiler/Parser + + - Fix bugs, missing features (some cause compliance regressions) + - Work on making the compiler interp-level + +* Built-in modules + + - Do we still miss important os.* functionality? + - errno + - Enable our own array/_sre when translating + - (Review builtin modules again to see if we missed something) + +* Fix/garden issues for the release in the tracker + + - Go over the issues in the tracker: close, postpone or fix them as needed + for the release + - Review Hildes_to_Heidel.txt contents too + +* Release + + - Documentation work + - Other: README, announcement, licenses & contributors... + - Release cutting & testing (important!) + - *try to be ready to cut on Friday morning!* + +* LLVM backend + + - Improvement work to stabilize and match genc + - (Try to share code with genc?) + +* GC + + - Complete SoC GC framework (cfbolz) + - (Start to think how/what is still missing to leverage it for Phase 2) + - (related: isolating refcounting) + +* Cleanups + + - We didn't really manage to tackle the cleanups listed in Hildes_to_Heidel.txt; + do we want, have we the time to address some of them during the sprint for the release + +* Future Planning + + - Plan work until next sprint + - Consider priorities up to review + - Start thinking about organizing Phase2 work, baseline status wrt this From cfbolz at codespeak.net Thu Aug 18 16:05:47 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 18 Aug 2005 16:05:47 +0200 (CEST) Subject: [pypy-svn] r16139 - pypy/dist/pypy/rpython/memory Message-ID: <20050818140547.8E23E27B86@code1.codespeak.net> Author: cfbolz Date: Thu Aug 18 16:05:46 2005 New Revision: 16139 Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: started cleaning up of all the different places that currently contain knowledge about the memory layout the lltypesimulation uses. Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Thu Aug 18 16:05:46 2005 @@ -27,6 +27,15 @@ typeid = self.type_to_typeid[TYPE] return typeid + def get_contained_pointers(self, addr, typeid): + TYPE = self.types[typeid] + ptr = lltypesimulation.simulatorptr(lltype.Ptr(TYPE), addr) + ll = AddressLinkedList() + offsets = ptr.get_offsets_of_contained_pointers() + for offset in offsets: + ll.append(addr + offset) + return ll + def get_roots(self): print "getting roots" if self.pseudo_root_pointers != NULL: @@ -43,50 +52,6 @@ ll.append(self.pseudo_root_pointers + INT_SIZE * i) return ll - def get_contained_pointers(self, addr, typeid): - TYPE = self.types[typeid] - if isinstance(TYPE, lltype.Struct): - offsets = self.get_contained_pointers_struct(addr, TYPE) - elif isinstance(TYPE, lltype.Array): - offsets = self.get_contained_pointers_array(addr, TYPE) - ll = AddressLinkedList() - for offset in offsets: - ll.append(addr + offset) - print "for the TYPE %s if found the follwing offsets: %s" % (TYPE, offsets) - return ll - - def get_contained_pointers_struct(self, addr, TYPE, offset=0): - offsets = [] - substructures = [(TYPE, offset)] - while len(substructures): - TYPE, offset = substructures.pop() - layout = lltypesimulation.get_layout(TYPE) - for name in TYPE._names: - FIELD = getattr(TYPE, name) - if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc(): - offsets.append(offset + layout[name]) - elif isinstance(FIELD, lltype.Struct): - substructures.append((FIELD, layout[name] + offset)) - elif isinstance(FIELD, lltype.Array): - assert offset == 0 #can only inline into outermost struct - baseaddr = addr + layout[name] - offsets += self.get_contained_pointers_array( - baseaddr, FIELD, layout[name]) - return offsets - - def get_contained_pointers_array(self, addr, TYPE, offset=0): - offsets = [] - length = addr.signed[0] - itemsize = lltypesimulation.get_variable_size(TYPE) - if isinstance(TYPE.OF, lltype.Ptr) and TYPE.OF._needsgc(): - for i in range(length): - offsets.append(offset + INT_SIZE + i * itemsize) - elif isinstance(TYPE.OF, lltype.GcStruct): - for i in range(length): - item_offset = INT_SIZE + i * itemsize - offsets += self.get_contained_pointers_array( - TYPE.OF, addr + item_offset, offset + item_offset) - return offsets class GcWrapper(object): def __init__(self, llinterp, gc): Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Thu Aug 18 16:05:46 2005 @@ -13,6 +13,12 @@ lltype.Bool: "B", } +INT_SIZE = struct.calcsize("i") + +#___________________________________________________________________________ +# Utility functions that know about the memory layout of the lltypes +# in the simulation + #returns some sort of layout information that is useful for the simulatorptr def get_layout(TYPE): layout = {} @@ -84,7 +90,7 @@ return fixedsize else: return fixedsize + i * varsize - + def _expose(T, address): """XXX A nice docstring here""" @@ -104,8 +110,10 @@ assert 0, "not implemented yet" +#_____________________________________________________________________________ # this class is intended to replace the _ptr class in lltype # using the memory simulator + class simulatorptr(object): def __init__(self, TYPE, address): self.__dict__['_TYPE'] = TYPE @@ -239,6 +247,38 @@ def __repr__(self): return '' % (self._TYPE.TO, self._address) + def get_offsets_of_contained_pointers(self): + if isinstance(self._TYPE.TO, lltype.Struct): + offsets = self._get_offsets_of_contained_pointers_struct() + elif isinstance(self._TYPE.TO, lltype.Array): + offsets = self._get_offsets_of_contained_pointers_array() + return offsets + + def _get_offsets_of_contained_pointers_struct(self): + offsets = [] + for name in self._TYPE.TO._names: + FIELD = getattr(self._TYPE.TO, name) + if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc(): + offsets.append(self._layout[name]) + elif isinstance(FIELD, (lltype.Struct, lltype.Array)): + embedded_ptr = getattr(self, name) + suboffsets = embedded_ptr.get_offsets_of_contained_pointers() + offsets += [s + self._layout[name] for s in suboffsets] + return offsets + + def _get_offsets_of_contained_pointers_array(self): + offsets = [] + if (isinstance(self._TYPE.TO.OF, lltype.Ptr) and + self._TYPE.TO.OF._needsgc()): + for i in range(len(self)): + offsets.append(self._layout[0] + i * self._layout[1]) + elif isinstance(self._TYPE.TO.OF, lltype.GcStruct): + for i in range(len(self)): + suboffsets += self[i].get_offsets_of_contained_pointers() + offsets += [s + self._layout[0] + i * self._layout[1] + for s in suboffsets] + return offsets + def cast_pointer(PTRTYPE, ptr): if not isinstance(ptr, simulatorptr) or not isinstance(PTRTYPE, lltype.Ptr): From cfbolz at codespeak.net Thu Aug 18 16:28:27 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 18 Aug 2005 16:28:27 +0200 (CEST) Subject: [pypy-svn] r16142 - pypy/dist/pypy/rpython/memory Message-ID: <20050818142827.AC4FD27B8A@code1.codespeak.net> Author: cfbolz Date: Thu Aug 18 16:28:27 2005 New Revision: 16142 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: rename get_total_size to sizeof Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Thu Aug 18 16:28:27 2005 @@ -1,5 +1,5 @@ from pypy.rpython.memory import lladdress -from pypy.rpython.memory.lltypesimulation import simulatorptr, get_total_size +from pypy.rpython.memory.lltypesimulation import simulatorptr, sizeof from pypy.rpython.memory.lltypesimulation import get_fixed_size from pypy.rpython.memory.lltypesimulation import get_variable_size from pypy.rpython.memory.lltypesimulation import primitive_to_fmt @@ -61,7 +61,7 @@ return address TYPE = lltype.typeOf(_array) arraylength = len(_array.items) - size = get_total_size(TYPE, arraylength) + size = sizeof(TYPE, arraylength) if inline_to_addr is not None: startaddr = inline_to_addr else: @@ -95,9 +95,9 @@ layout = get_layout(TYPE) if TYPE._arrayfld is not None: inlinedarraylength = len(getattr(_struct, TYPE._arrayfld).items) - size = get_total_size(TYPE, inlinedarraylength) + size = sizeof(TYPE, inlinedarraylength) else: - size = get_total_size(TYPE) + size = sizeof(TYPE) if inline_to_addr is not None: startaddr = inline_to_addr else: @@ -182,7 +182,7 @@ elif isinstance(cand, lltype._array): seen[cand] = True length = len(cand.items) - total_size += get_total_size(cand._TYPE, length) * 2 * INT_SIZE + total_size += sizeof(cand._TYPE, length) * 2 * INT_SIZE for item in cand.items: candidates.append(item) elif isinstance(cand, lltype._struct): @@ -196,10 +196,10 @@ TYPE = cand._TYPE if not has_parent: if TYPE._arrayfld is not None: - total_size += get_total_size( + total_size += sizeof( TYPE, len(getattr(cand, TYPE._arrayfld).items)) else: - total_size += get_total_size(TYPE) + total_size += sizeof(TYPE) total_size += INT_SIZE * 2 for name in TYPE._flds: candidates.append(getattr(cand, name)) Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Thu Aug 18 16:28:27 2005 @@ -63,7 +63,7 @@ def malloc(self, TYPE, size=0): typeid = self.objectmodel.get_typeid(TYPE) address = self.gc.malloc(typeid, - lltypesimulation.get_total_size(TYPE, size)) + lltypesimulation.sizeof(TYPE, size)) result = lltypesimulation.simulatorptr(lltype.Ptr(TYPE), address) result._zero_initialize(size) result._init_size(size) Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Thu Aug 18 16:28:27 2005 @@ -82,7 +82,7 @@ else: assert 0, "not yet implemented" -def get_total_size(TYPE, i=None): +def sizeof(TYPE, i=None): fixedsize = get_fixed_size(TYPE) varsize = get_variable_size(TYPE) if i is None: @@ -122,7 +122,7 @@ self.__dict__['_layout'] = get_layout(TYPE.TO) def _zero_initialize(self, i=None): - size = get_total_size(self._T, i) + size = sizeof(self._T, i) self._address._store("c" * size, *(["\x00"] * size)) def _init_size(self, size): From pedronis at codespeak.net Thu Aug 18 16:55:06 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 18 Aug 2005 16:55:06 +0200 (CEST) Subject: [pypy-svn] r16143 - pypy/dist/pypy/rpython/memory Message-ID: <20050818145506.8829727B8A@code1.codespeak.net> Author: pedronis Date: Thu Aug 18 16:55:05 2005 New Revision: 16143 Modified: pypy/dist/pypy/rpython/memory/lladdress.py Log: set _TYPE for address instances Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 18 16:55:05 2005 @@ -108,6 +108,7 @@ from pypy.rpython import lltype Address = lltype.Primitive("Address", NULL) +address._TYPE = Address supported_access_types = {"signed": lltype.Signed, "unsigned": lltype.Unsigned, From cfbolz at codespeak.net Thu Aug 18 17:31:47 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 18 Aug 2005 17:31:47 +0200 (CEST) Subject: [pypy-svn] r16144 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050818153147.6515B27B8C@code1.codespeak.net> Author: cfbolz Date: Thu Aug 18 17:31:46 2005 New Revision: 16144 Modified: pypy/dist/pypy/rpython/memory/lladdress.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: oops, missing nonzero. thanks samuele Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 18 17:31:46 2005 @@ -42,6 +42,10 @@ def _store(self, fmt, *values): simulator.setstruct(fmt, self.intaddress, *values) + def __nonzero__(self): + return self.intaddress != 0 + + class _accessor(object): def __init__(self, addr): if addr == NULL: Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 18 17:31:46 2005 @@ -184,6 +184,13 @@ assert address() is NULL assert address() is address(0) + def test_convert_to_bool(self): + assert not address() + assert not NULL + assert address(1) + assert address(2) + assert bool(address(3)) + def test_memory_access(self): addr = raw_malloc(1000) addr.signed[0] = -1 From pedronis at codespeak.net Thu Aug 18 17:48:19 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 18 Aug 2005 17:48:19 +0200 (CEST) Subject: [pypy-svn] r16145 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050818154819.54B7527B8D@code1.codespeak.net> Author: pedronis Date: Thu Aug 18 17:48:14 2005 New Revision: 16145 Added: pypy/dist/pypy/rpython/raddress.py - copied, changed from r16139, pypy/dist/pypy/rpython/rptr.py Modified: pypy/dist/pypy/rpython/memory/test/test_address.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rtyper.py Log: rtyping of address operations, first cut Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 18 17:48:14 2005 @@ -112,7 +112,7 @@ class TestAddressRTyping(object): - def DONOTtest_null(self): + def test_null(self): def f(): return NULL a = RPythonAnnotator() @@ -122,7 +122,7 @@ rtyp = a.translator.flowgraphs[f].returnblock.inputargs[0].concretetype assert rtyp == Address - def DONOTtest_raw_malloc(self): + def test_raw_malloc(self): def f(): return raw_malloc(100) a = RPythonAnnotator() @@ -130,7 +130,7 @@ rtyper = RPythonTyper(a) rtyper.specialize() #does not raise - def DONOTtest_raw_free(self): + def test_raw_free(self): def f(addr): raw_free(addr) a = RPythonAnnotator() @@ -138,7 +138,7 @@ rtyper = RPythonTyper(a) rtyper.specialize() #does not raise - def DONOTtest_memcopy(self): + def test_memcopy(self): def f(addr1, addr2): raw_memcopy(addr1, addr2, 100) a = RPythonAnnotator() @@ -147,7 +147,7 @@ rtyper = RPythonTyper(a) rtyper.specialize() #does not raise - def DONOTtest_memory_access(self): + def test_memory_access(self): def f(offset, value): addr = raw_malloc(offset * 2 + 1) addr.signed[offset] = value @@ -157,7 +157,7 @@ rtyper = RPythonTyper(a) rtyper.specialize() #does not raise - def DONOTtest_address_arithmetic(self): + def test_address_arithmetic(self): def f(offset, char): addr = raw_malloc(10000) same_offset = (addr + offset) - addr @@ -168,7 +168,7 @@ rtyper = RPythonTyper(a) rtyper.specialize() #does not raise - def DONOTtest_address_comparison(self): + def test_address_comparison(self): def f(offset): return NULL < NULL + offset a = RPythonAnnotator() Copied: pypy/dist/pypy/rpython/raddress.py (from r16139, pypy/dist/pypy/rpython/rptr.py) ============================================================================== --- pypy/dist/pypy/rpython/rptr.py (original) +++ pypy/dist/pypy/rpython/raddress.py Thu Aug 18 17:48:14 2005 @@ -1,123 +1,109 @@ +# rtyping of memory address operations from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Ptr, _ptr -from pypy.rpython.lltype import ContainerType, Void, Signed, Bool, FuncType +from pypy.rpython.memory.lladdress import address, NULL, Address from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst +from pypy.rpython import lltype - -class __extend__(annmodel.SomePtr): +class __extend__(annmodel.SomeAddress): def rtyper_makerepr(self, rtyper): -## if self.is_constant() and not self.const: # constant NULL -## return nullptr_repr -## else: - return PtrRepr(self.ll_ptrtype) + return address_repr + def rtyper_makekey(self): -## if self.is_constant() and not self.const: -## return None -## else: - return self.__class__, self.ll_ptrtype + return self.__class__, + +class __extend__(annmodel.SomeTypedAddressAccess): + def rtyper_makerepr(self, rtyper): + return TypedAddressAccessRepr(self.type) + def rtyper_makekey(self): + return self.__class__, self.type -class PtrRepr(Repr): +class AddressRepr(Repr): + lowleveltype = Address - def __init__(self, ptrtype): - assert isinstance(ptrtype, Ptr) - self.lowleveltype = ptrtype + def convert_const(self, value): + assert value is NULL + return NULL def rtype_getattr(self, hop): - attr = hop.args_s[1].const - FIELD_TYPE = getattr(self.lowleveltype.TO, attr) - if isinstance(FIELD_TYPE, ContainerType): - newopname = 'getsubstruct' - else: - newopname = 'getfield' - vlist = hop.inputargs(self, Void) - return hop.genop(newopname, vlist, - resulttype = hop.r_result.lowleveltype) - - def rtype_setattr(self, hop): - attr = hop.args_s[1].const - FIELD_TYPE = getattr(self.lowleveltype.TO, attr) - assert not isinstance(FIELD_TYPE, ContainerType) - vlist = hop.inputargs(self, Void, hop.args_r[2]) - hop.genop('setfield', vlist) - - def rtype_len(self, hop): - vlist = hop.inputargs(self) - return hop.genop('getarraysize', vlist, - resulttype = hop.r_result.lowleveltype) - - def rtype_is_true(self, hop): - vlist = hop.inputargs(self) - return hop.genop('ptr_nonzero', vlist, resulttype=Bool) - - def rtype_simple_call(self, hop): - if not isinstance(self.lowleveltype.TO, FuncType): - raise TyperError("calling a non-function %r", self.lowleveltype.TO) - vlist = hop.inputargs(*hop.args_r) - hop.exception_is_here() - return hop.genop('direct_call', vlist, - resulttype = self.lowleveltype.TO.RESULT) - - -class __extend__(pairtype(PtrRepr, IntegerRepr)): - - def rtype_getitem((r_ptr, r_int), hop): - ARRAY = r_ptr.lowleveltype.TO - ITEM_TYPE = ARRAY.OF - if isinstance(ITEM_TYPE, ContainerType): - newopname = 'getarraysubstruct' - else: - newopname = 'getarrayitem' - vlist = hop.inputargs(r_ptr, Signed) - return hop.genop(newopname, vlist, - resulttype = hop.r_result.lowleveltype) - - def rtype_setitem((r_ptr, r_int), hop): - ARRAY = r_ptr.lowleveltype.TO - ITEM_TYPE = ARRAY.OF - assert not isinstance(ITEM_TYPE, ContainerType) - vlist = hop.inputargs(r_ptr, Signed, hop.args_r[2]) - hop.genop('setarrayitem', vlist) - -# ____________________________________________________________ -# -# Null Pointers - -##class NullPtrRepr(Repr): -## lowleveltype = Void - -## def rtype_is_true(self, hop): -## return hop.inputconst(Bool, False) - -##nullptr_repr = NullPtrRepr() - -##class __extend__(pairtype(NullPtrRepr, PtrRepr)): -## def convert_from_to((r_null, r_ptr), v, llops): -## # nullptr to general pointer -## return inputconst(r_ptr, _ptr(r_ptr.lowleveltype, None)) - -# ____________________________________________________________ -# -# Comparisons - -class __extend__(pairtype(PtrRepr, Repr)): - - def rtype_eq((r_ptr, r_any), hop): - vlist = hop.inputargs(r_ptr, r_ptr) - return hop.genop('ptr_eq', vlist, resulttype=Bool) - - def rtype_ne((r_ptr, r_any), hop): - vlist = hop.inputargs(r_ptr, r_ptr) - return hop.genop('ptr_ne', vlist, resulttype=Bool) - - -class __extend__(pairtype(Repr, PtrRepr)): - - def rtype_eq((r_any, r_ptr), hop): - vlist = hop.inputargs(r_ptr, r_ptr) - return hop.genop('ptr_eq', vlist, resulttype=Bool) - - def rtype_ne((r_any, r_ptr), hop): - vlist = hop.inputargs(r_ptr, r_ptr) - return hop.genop('ptr_ne', vlist, resulttype=Bool) + v_access = hop.inputarg(address_repr, 0) + return v_access + + +address_repr = AddressRepr() + + +class TypedAddressAccessRepr(Repr): + lowleveltype = Address + + def __init__(self, typ): + self.type = typ + + +class __extend__(pairtype(TypedAddressAccessRepr, IntegerRepr)): + + def rtype_getitem((r_acc, r_int), hop): + c_type = hop.inputconst(lltype.Void, r_acc.type) + v_addr, v_offs = hop.inputargs(hop.args_r[0], lltype.Signed) + return hop.genop('raw_load', [v_addr, c_type, v_offs], + resulttype = r_acc.type) + + def rtype_setitem((r_acc, r_int), hop): + c_type = hop.inputconst(lltype.Void, r_acc.type) + v_addr, v_offs, v_value = hop.inputargs(hop.args_r[0], lltype.Signed, r_acc.type) + return hop.genop('raw_store', [v_addr, c_type, v_offs, v_value]) + + +class __extend__(pairtype(AddressRepr, IntegerRepr)): + + def rtype_add((r_addr, r_int), hop): + if r_int.lowleveltype == lltype.Signed: + v_addr, v_offs = hop.inputargs(Address, lltype.Signed) + return hop.genop('adr_add', [v_addr, v_offs], resulttype=Address) + + return NotImplemented + + def rtype_sub((r_addr, r_int), hop): + if r_int.lowleveltype == lltype.Signed: + v_addr, v_offs = hop.inputargs(Address, lltype.Signed) + return hop.genop('adr_sub', [v_addr, v_offs], resulttype=Address) + + return NotImplemented + +class __extend__(pairtype(IntegerRepr, AddressRepr)): + + def rtype_add((r_int, r_addr), hop): + return pair(r_addr, r_int).rtype_add(hop) + + +class __extend__(pairtype(AddressRepr, AddressRepr)): + + def rtype_sub((r_addr1, r_addr2), hop): + v_addr1, v_addr2 = hop.inputargs(Address, Address) + return hop.genop('adr_delta', [v_addr1, v_addr2], resulttype=lltype.Signed) + + def rtype_eq((r_addr1, r_addr2), hop): + v_addr1, v_addr2 = hop.inputargs(Address, Address) + return hop.genop('adr_eq', [v_addr1, v_addr2], resulttype=lltype.Bool) + + def rtype_ne((r_addr1, r_addr2), hop): + v_addr1, v_addr2 = hop.inputargs(Address, Address) + return hop.genop('adr_ne', [v_addr1, v_addr2], resulttype=lltype.Bool) + + def rtype_lt((r_addr1, r_addr2), hop): + v_addr1, v_addr2 = hop.inputargs(Address, Address) + return hop.genop('adr_lt', [v_addr1, v_addr2], resulttype=lltype.Bool) + + def rtype_le((r_addr1, r_addr2), hop): + v_addr1, v_addr2 = hop.inputargs(Address, Address) + return hop.genop('adr_le', [v_addr1, v_addr2], resulttype=lltype.Bool) + + def rtype_gt((r_addr1, r_addr2), hop): + v_addr1, v_addr2 = hop.inputargs(Address, Address) + return hop.genop('adr_gt', [v_addr1, v_addr2], resulttype=lltype.Bool) + + def rtype_ge((r_addr1, r_addr2), hop): + v_addr1, v_addr2 = hop.inputargs(Address, Address) + return hop.genop('adr_ge', [v_addr1, v_addr2], resulttype=lltype.Bool) + Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Thu Aug 18 17:48:14 2005 @@ -296,3 +296,23 @@ for func, extfuncinfo in extfunctable.table.iteritems(): BUILTIN_TYPER[func] = make_rtype_extfunc(extfuncinfo) +# _________________________________________________________________ +# memory addresses + +from pypy.rpython.memory import lladdress + +def rtype_raw_malloc(hop): + v_size, = hop.inputargs(lltype.Signed) + return hop.genop('raw_malloc', [v_size], resulttype=lladdress.Address) + +def rtype_raw_free(hop): + v_addr, = hop.inputargs(lladdress.Address) + return hop.genop('raw_free', [v_addr]) + +def rtype_raw_memcopy(hop): + v_list = hop.inputargs(lladdress.Address, lladdress.Address, lltype.Signed) + return hop.genop('raw_memcopy', v_list) + +BUILTIN_TYPER[lladdress.raw_malloc] = rtype_raw_malloc +BUILTIN_TYPER[lladdress.raw_free] = rtype_raw_free +BUILTIN_TYPER[lladdress.raw_memcopy] = rtype_raw_memcopy Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Thu Aug 18 17:48:14 2005 @@ -742,3 +742,4 @@ from pypy.rpython import rlist, rstr, rtuple, rdict from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase from pypy.rpython import rptr +from pypy.rpython import raddress # memory addresses From cfbolz at codespeak.net Thu Aug 18 17:48:25 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 18 Aug 2005 17:48:25 +0200 (CEST) Subject: [pypy-svn] r16146 - pypy/dist/pypy/rpython/memory Message-ID: <20050818154825.B797727B95@code1.codespeak.net> Author: cfbolz Date: Thu Aug 18 17:48:24 2005 New Revision: 16146 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gclltype.py Log: made convertlltype independent of the gc being used. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Thu Aug 18 17:48:24 2005 @@ -18,12 +18,13 @@ INT_SIZE = struct.calcsize("i") class LLTypeConverter(object): - def __init__(self, address): + def __init__(self, address, gc=None): self.type_to_typeid = {} self.types = [] self.converted = {} self.curraddress = address self.constantroots = [] + self.gc = gc def get_typeid(self, TYPE): if TYPE not in self.type_to_typeid: @@ -66,12 +67,14 @@ startaddr = inline_to_addr else: startaddr = self.curraddress - startaddr.signed[0] = 0 - startaddr.signed[1] = self.get_typeid(TYPE) - startaddr += 2 * INT_SIZE + if self.gc is not None: + self.gc.init_gc_object(startaddr, self.get_typeid(TYPE)) + startaddr += self.gc.size_gc_header() self.constantroots.append( simulatorptr(lltype.Ptr(TYPE), startaddr)) - self.curraddress += size + 2 * INT_SIZE + self.curraddress += size + if self.gc is not None: + self.curraddress += self.gc.size_gc_header() self.converted[_array] = startaddr startaddr.signed[0] = arraylength curraddr = startaddr + get_fixed_size(TYPE) @@ -102,12 +105,14 @@ startaddr = inline_to_addr else: startaddr = self.curraddress - startaddr.signed[0] = 0 - startaddr.signed[1] = self.get_typeid(TYPE) - startaddr += 2 * INT_SIZE + if self.gc is not None: + self.gc.init_gc_object(startaddr, self.get_typeid(TYPE)) + startaddr += self.gc.size_gc_header() self.constantroots.append( simulatorptr(lltype.Ptr(TYPE), startaddr)) - self.curraddress += size + 2 * INT_SIZE + self.curraddress += size + if self.gc is not None: + self.curraddress += self.gc.size_gc_header() self.converted[_struct] = startaddr for name in TYPE._flds: addr = startaddr + layout[name] @@ -132,11 +137,12 @@ return lladdress.get_address_of_object(_obj) class FlowGraphConstantConverter(object): - def __init__(self, flowgraphs): + def __init__(self, flowgraphs, gc=None): self.flowgraphs = flowgraphs self.memory = lladdress.NULL self.cvter = None self.total_size = 0 + self.gc = gc def collect_constants(self): constants = {} @@ -182,7 +188,9 @@ elif isinstance(cand, lltype._array): seen[cand] = True length = len(cand.items) - total_size += sizeof(cand._TYPE, length) * 2 * INT_SIZE + total_size += sizeof(cand._TYPE, length) + if self.gc is not None: + total_size += self.gc.size_gc_header() for item in cand.items: candidates.append(item) elif isinstance(cand, lltype._struct): @@ -200,7 +208,8 @@ TYPE, len(getattr(cand, TYPE._arrayfld).items)) else: total_size += sizeof(TYPE) - total_size += INT_SIZE * 2 + if self.gc is not None: + total_size += self.gc.size_gc_header() for name in TYPE._flds: candidates.append(getattr(cand, name)) elif isinstance(cand, lltype._opaque): @@ -215,7 +224,7 @@ def convert_constants(self): self.memory = lladdress.raw_malloc(self.total_size) - self.cvter = LLTypeConverter(self.memory) + self.cvter = LLTypeConverter(self.memory, self.gc) for constant in self.constants.iterkeys(): if isinstance(constant.value, lltype.LowLevelType): self.constants[constant] = constant.value Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Aug 18 17:48:24 2005 @@ -1,9 +1,9 @@ from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL from pypy.rpython.memory.support import AddressLinkedList +from pypy.rpython import lltype +from pypy.rpython.memory import lltypesimulation import struct -INT_SIZE = struct.calcsize("i") - class GCError(Exception): pass @@ -22,6 +22,7 @@ class MarkSweepGC(object): _raw_allocate_ = True + def __init__(self, objectmodel, collect_every_bytes): self.bytes_malloced = 0 self.collect_every_bytes = collect_every_bytes @@ -33,14 +34,13 @@ def malloc(self, typeid, size): if self.bytes_malloced > self.collect_every_bytes: self.collect() - result = raw_malloc(size + 2 * INT_SIZE) + size_gc_header = self.size_gc_header() + result = raw_malloc(size + size_gc_header) print "mallocing %s, size %s at %s" % (typeid, size, result) - print "real size: %s" % (size + 2 * INT_SIZE, ) - result.signed[0] = 0 - result.signed[1] = typeid + self.init_gc_object(result, typeid) self.malloced_objects.append(result) - self.bytes_malloced += size + 2 * INT_SIZE - return result + 2 * INT_SIZE + self.bytes_malloced += size + size_gc_header + return result + size_gc_header def collect(self): print "collecting" @@ -54,7 +54,7 @@ break # roots is a list of addresses to addresses: objects.append(curr.address[0]) - gc_info = curr.address[0] - 2 * INT_SIZE + gc_info = curr.address[0] - self.size_gc_header() # constants roots are not malloced and thus don't have their mark # bit reset gc_info.signed[0] = 0 @@ -63,7 +63,7 @@ print "object: ", curr if curr == NULL: break - gc_info = curr - 2 * INT_SIZE + gc_info = curr - self.size_gc_header() if gc_info.signed[0] == 1: continue pointers = self.objectmodel.get_contained_pointers( @@ -86,3 +86,12 @@ raw_free(curr) free_non_gc_object(self.malloced_objects) self.malloced_objects = newmo + + def size_gc_header(self): + return lltypesimulation.sizeof(lltype.Signed) * 2 + + + def init_gc_object(self, addr, typeid): + addr.signed[0] = 0 + addr.signed[1] = typeid + Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Thu Aug 18 17:48:24 2005 @@ -38,12 +38,14 @@ def create_mark_sweep_gc(llinterp, flowgraphs): from pypy.rpython.memory.gcwrapper import GcWrapper, LLInterpObjectModel from pypy.rpython.memory.gc import MarkSweepGC - fgcc = FlowGraphConstantConverter(flowgraphs) + #XXX hackish: we need the gc before the object model is ready + gc = MarkSweepGC(None, 4096) + fgcc = FlowGraphConstantConverter(flowgraphs, gc) fgcc.convert() om = LLInterpObjectModel(llinterp, fgcc.cvter.types, fgcc.cvter.type_to_typeid, fgcc.cvter.constantroots) - gc = MarkSweepGC(om, 4096) + gc.objectmodel = om wrapper = GcWrapper(llinterp, gc) return wrapper From pedronis at codespeak.net Thu Aug 18 17:56:04 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 18 Aug 2005 17:56:04 +0200 (CEST) Subject: [pypy-svn] r16147 - pypy/dist/pypy/rpython Message-ID: <20050818155604.834C027B8D@code1.codespeak.net> Author: pedronis Date: Thu Aug 18 17:56:02 2005 New Revision: 16147 Modified: pypy/dist/pypy/rpython/raddress.py Log: this doesn't work Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Thu Aug 18 17:56:02 2005 @@ -71,11 +71,6 @@ return NotImplemented -class __extend__(pairtype(IntegerRepr, AddressRepr)): - - def rtype_add((r_int, r_addr), hop): - return pair(r_addr, r_int).rtype_add(hop) - class __extend__(pairtype(AddressRepr, AddressRepr)): From arigo at codespeak.net Thu Aug 18 18:02:22 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 18 Aug 2005 18:02:22 +0200 (CEST) Subject: [pypy-svn] r16148 - pypy/dist/pypy/module/_codecs/test Message-ID: <20050818160222.664BE27B8A@code1.codespeak.net> Author: arigo Date: Thu Aug 18 18:02:22 2005 New Revision: 16148 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: The string_escape codec is still broken. See tests and especially the comments in the tests. Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Thu Aug 18 18:02:22 2005 @@ -41,9 +41,15 @@ assert u"\u0663".encode("raw-unicode-escape") == "\u0663" def test_escape_decode(self): + skip("XXX fix the string_escape codecs (see comments in the tset)") + # XXX comments: + # - string_escape does not support \u and \U at all + # - this sequence of 'if' statements should be 'elif', otherwise + # two cases can mix with each other + # - see more tests below test = 'a\n\\b\x00c\td\u2045'.encode('string_escape') assert test.decode('string_escape') =='a\n\\b\x00c\td\u2045' - # skip("string_escape has open bugs") assert '\\077'.decode('string_escape') == '?' - assert '\\u1234'.decode('string_escape') == '\u1234' - assert '\\x41u1234'.decode('string_escape') == 'Au1234' + assert '\\100'.decode('string_escape') == '@' + assert '\\253'.decode('string_escape') == chr(0253) + assert '\\312'.decode('string_escape') == chr(0312) From pedronis at codespeak.net Thu Aug 18 18:29:00 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 18 Aug 2005 18:29:00 +0200 (CEST) Subject: [pypy-svn] r16149 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050818162900.672C127B8C@code1.codespeak.net> Author: pedronis Date: Thu Aug 18 18:28:58 2005 New Revision: 16149 Modified: pypy/dist/pypy/rpython/memory/test/test_address.py pypy/dist/pypy/rpython/raddress.py Log: rtyping of is_true for addresses Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Thu Aug 18 18:28:58 2005 @@ -157,6 +157,21 @@ rtyper = RPythonTyper(a) rtyper.specialize() #does not raise + def test_addr_as_bool(self): + def f(addr1, addr2): + if addr1: + return 1 + else: + if not addr2: + return 0 + else: + return -1 + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, [annmodel.SomeAddress(), annmodel.SomeAddress()]) + rtyper = RPythonTyper(a) + rtyper.specialize() #does not raise + def test_address_arithmetic(self): def f(offset, char): addr = raw_malloc(10000) Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Thu Aug 18 18:28:58 2005 @@ -30,6 +30,12 @@ v_access = hop.inputarg(address_repr, 0) return v_access + def rtype_is_true(self, hop): + v_addr, = hop.inputargs(address_repr) + c_null = hop.inputconst(address_repr, NULL) + return hop.genop('adr_ne', [v_addr, c_null], + resulttype=lltype.Bool) + address_repr = AddressRepr() From ale at codespeak.net Thu Aug 18 19:33:48 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 18 Aug 2005 19:33:48 +0200 (CEST) Subject: [pypy-svn] r16150 - in pypy/dist/pypy/module/_codecs: . test Message-ID: <20050818173348.8941D27B8C@code1.codespeak.net> Author: ale Date: Thu Aug 18 19:33:47 2005 New Revision: 16150 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: changed as per Armins suggestions (Thanks Armin) Enabled the tests Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Thu Aug 18 19:33:47 2005 @@ -293,40 +293,32 @@ i += 1 if data[i] == '\\': res += '\\' - if data[i] == 'n': + elif data[i] == 'n': res += '\n' - if data[i] == 't': + elif data[i] == 't': res += '\t' - if data[i] == 'r': + elif data[i] == 'r': res += '\r' - if data[i] == 'b': + elif data[i] == 'b': res += '\b' - if data[i] == '\'': + elif data[i] == '\'': res += '\'' - if data[i] == '\"': + elif data[i] == '\"': res += '\"' - if data[i] == 'f': + elif data[i] == 'f': res += '\f' - if data[i] == 'a': + elif data[i] == 'a': res += '\a' - if data[i] == 'v': + elif data[i] == 'v': res += '\v' - if data[i] == '0': - octal = data[i+1:i+3] + elif data[i] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: + octal = data[i:i+3] res += chr(int(octal,8)) i += 2 - if data[i] == 'x': + elif data[i] == 'x': hexa = data[i+1:i+3] res += chr(int(hexa,16)) i += 2 - if data[i] == 'u': - res += data[i-1:i+5] - i += 4 - if data[i] == 'U': - res += data[i-1:i+9] - i += 8 - if data[i] == 'N': - raise NotImplementedError else: res += data[i] i += 1 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Thu Aug 18 19:33:47 2005 @@ -41,12 +41,7 @@ assert u"\u0663".encode("raw-unicode-escape") == "\u0663" def test_escape_decode(self): - skip("XXX fix the string_escape codecs (see comments in the tset)") - # XXX comments: - # - string_escape does not support \u and \U at all - # - this sequence of 'if' statements should be 'elif', otherwise - # two cases can mix with each other - # - see more tests below + test = 'a\n\\b\x00c\td\u2045'.encode('string_escape') assert test.decode('string_escape') =='a\n\\b\x00c\td\u2045' assert '\\077'.decode('string_escape') == '?' From cfbolz at codespeak.net Fri Aug 19 12:05:38 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 12:05:38 +0200 (CEST) Subject: [pypy-svn] r16157 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050819100538.E90DE27B86@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 12:05:37 2005 New Revision: 16157 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: add operations neccessary for using addresses in the llinterpreter Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Aug 19 12:05:37 2005 @@ -4,6 +4,7 @@ from pypy.rpython.rarithmetic import intmask, r_uint, ovfcheck from pypy.rpython import lltype from pypy.rpython.rmodel import getfunctionptr +from pypy.rpython.memory import lladdress import math import py @@ -432,7 +433,46 @@ assert self.llt.typeOf(pyo) == self.llt.Ptr(self.llt.PyObject) res = f._obj.value(*[pyo._obj.value for pyo in args]) return self.llt.pyobjectptr(res) - + + # __________________________________________________________ + # operations on addresses + + def op_raw_malloc(self, size): + assert self.llt.typeOf(size) == self.llt.Signed + return lladdress.raw_malloc(size) + + def op_raw_load(self, addr, typ, offset): + assert isinstance(addr, lladdress.address) + value = getattr(addr, str(typ).lower())[offset] + assert self.llt.typeOf(value) == typ + return value + + def op_raw_store(self, addr, typ, offset, value): + assert isinstance(addr, lladdress.address) + assert self.llt.typeOf(value) == typ + getattr(addr, str(typ).lower())[offset] = value + + def op_adr_ne(self, addr1, addr2): + assert isinstance(addr1, lladdress.address) + assert isinstance(addr2, lladdress.address) + return addr1 != addr2 + + def op_adr_add(self, addr, offset): + assert isinstance(addr, lladdress.address) + assert self.llt.typeOf(offset) is self.llt.Signed + return addr + offset + + def op_adr_sub(self, addr, offset): + assert isinstance(addr, lladdress.address) + assert self.llt.typeOf(offset) is self.llt.Signed + return addr - offset + + def op_adr_delta(self, addr1, addr2): + assert isinstance(addr1, lladdress.address) + assert isinstance(addr2, lladdress.address) + return addr1 - addr2 + + # __________________________________________________________ # primitive operations Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Fri Aug 19 12:05:37 2005 @@ -10,6 +10,7 @@ from pypy.rpython.memory.lladdress import get_py_object, get_address_of_object from pypy.rpython.memory.lladdress import Address from pypy.rpython.memory.simulator import MemorySimulatorError +from pypy.rpython.memory.test.test_llinterpsim import interpret class TestAddressAnnotation(object): def test_null(self): @@ -122,6 +123,13 @@ rtyp = a.translator.flowgraphs[f].returnblock.inputargs[0].concretetype assert rtyp == Address + def test_convert_to_bool(self): + def f(addr): + return bool(addr) + a = RPythonAnnotator() + s = a.build_types(f, [annmodel.SomeAddress()]) + assert isinstance(s, annmodel.SomeBool) + def test_raw_malloc(self): def f(): return raw_malloc(100) @@ -193,6 +201,41 @@ graph = a.translator.flowgraphs[f] assert graph.startblock.operations[0].result.concretetype == Address +class TestAddressInLLInterp(object): + def test_null(self): + def f(): + return NULL + assert interpret(f, []) is NULL + + def test_convert_to_bool(self): + def f(addr): + return bool(addr) + res = interpret(f, [NULL]) + assert isinstance(res, bool) and not res + res = interpret(f, [address(1)]) + assert isinstance(res, bool) and res + + def test_memory_access(self): + def f(value): + addr = raw_malloc(16) + addr.signed[0] = value + return addr.signed[0] + res = interpret(f, [42]) + assert res == 42 + res = interpret(f, [1]) + assert res == 1 + + + def test_pointer_arithmetic(self): + def f(offset, char): + addr = raw_malloc(10000) + same_offset = (addr + 2 * offset - offset) - addr + addr.char[offset] = char + return (addr + same_offset).char[0] + res = interpret(f, [10, "c"]) + assert res == "c" + res = interpret(f, [12, "x"]) + assert res == "x" class TestAddressSimulation(object): def test_null_is_singleton(self): From cfbolz at codespeak.net Fri Aug 19 12:25:50 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 12:25:50 +0200 (CEST) Subject: [pypy-svn] r16158 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050819102550.5153727B8A@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 12:25:49 2005 New Revision: 16158 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: implemented address comparisons Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Aug 19 12:25:49 2005 @@ -452,11 +452,6 @@ assert self.llt.typeOf(value) == typ getattr(addr, str(typ).lower())[offset] = value - def op_adr_ne(self, addr1, addr2): - assert isinstance(addr1, lladdress.address) - assert isinstance(addr2, lladdress.address) - return addr1 != addr2 - def op_adr_add(self, addr, offset): assert isinstance(addr, lladdress.address) assert self.llt.typeOf(offset) is self.llt.Signed @@ -472,7 +467,14 @@ assert isinstance(addr2, lladdress.address) return addr1 - addr2 - + for opname, op in (("eq", "=="), ("ne", "!="), ("le", "<="), ("lt", "<"), + ("gt", ">"), ("ge", ">=")): + exec py.code.Source(""" + def op_adr_%s(self, addr1, addr2): + assert isinstance(addr1, lladdress.address) + assert isinstance(addr2, lladdress.address) + return addr1 %s addr2""" % (opname, op)).compile() + # __________________________________________________________ # primitive operations Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Fri Aug 19 12:25:49 2005 @@ -225,7 +225,6 @@ res = interpret(f, [1]) assert res == 1 - def test_pointer_arithmetic(self): def f(offset, char): addr = raw_malloc(10000) @@ -237,6 +236,17 @@ res = interpret(f, [12, "x"]) assert res == "x" + def test_address_comparison(self): + def f(offset): + return NULL < NULL + offset or NULL == NULL + offset + res = interpret(f, [10]) + assert res + res = interpret(f, [-10]) + assert not res + res = interpret(f, [0]) + assert res + + class TestAddressSimulation(object): def test_null_is_singleton(self): assert address() is NULL From cfbolz at codespeak.net Fri Aug 19 13:35:27 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 13:35:27 +0200 (CEST) Subject: [pypy-svn] r16159 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050819113527.0984627B86@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 13:35:27 2005 New Revision: 16159 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/support.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: added a failing test that tries to annotate a class with (the former) _raw_alloc_ = True. _raw_alloc_ = True was changed (as to samuele's suggestion) to _alloc_flavor_ = "". The plan is that the flavor is passed to malloc which then decides what to do with it. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Fri Aug 19 13:35:27 2005 @@ -15,13 +15,13 @@ def free_non_gc_object(obj): - assert getattr(obj.__class__, "_raw_allocate_", False), "trying to free regular object" + assert getattr(obj.__class__, "_alloc_flavor_", False) == "", "trying to free regular object" obj.__dict__ = {} obj.__class__ = FREED_OBJECT class MarkSweepGC(object): - _raw_allocate_ = True + _alloc_flavor_ = "" def __init__(self, objectmodel, collect_every_bytes): self.bytes_malloced = 0 Modified: pypy/dist/pypy/rpython/memory/support.py ============================================================================== --- pypy/dist/pypy/rpython/memory/support.py (original) +++ pypy/dist/pypy/rpython/memory/support.py Fri Aug 19 13:35:27 2005 @@ -5,7 +5,7 @@ INT_SIZE = struct.calcsize("i") class AddressLinkedList(object): - _raw_allocate_ = True + _alloc_flavor_ = "" def __init__(self): self.first = NULL self.last = NULL Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 19 13:35:27 2005 @@ -1,5 +1,8 @@ import py +from pypy.annotation import model as annmodel +from pypy.translator.annrpython import RPythonAnnotator +from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.memory.gc import free_non_gc_object, GCError, MarkSweepGC from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL @@ -19,7 +22,7 @@ def test_free_non_gc_object(): class TestClass(object): - _raw_allocate_ = True + _alloc_flavor_ = "" def __init__(self, a): self.a = a def method1(self): @@ -37,6 +40,26 @@ py.test.raises(GCError, "t.a") py.test.raises(AssertionError, "free_non_gc_object(TestClass2())") +def DONOTtest_rtype_free_non_gc_object(): + class TestClass(object): + _alloc_flavor_ = "" + def __init__(self, a): + self.a = a + def method1(self): + return self.a + def method2(self): + return 42 + def malloc_and_free(a): + ci = TestClass(a) + b = ci.a + free_non_gc_object(ci) + return b + a = RPythonAnnotator() + #does not raise: + s = a.build_types(malloc_and_free, [annmodel.SomeAddress()]) + assert isinstance(s, annmodel.SomeAddress) + rtyper = RPythonTyper(a) + rtyper.specialize() class PseudoObjectModel(object): """Object model for testing purposes: you can specify roots and a From cfbolz at codespeak.net Fri Aug 19 14:13:32 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 14:13:32 +0200 (CEST) Subject: [pypy-svn] r16160 - in pypy/dist/pypy/rpython: . memory memory/test test Message-ID: <20050819121332.667BC27B86@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 14:13:27 2005 New Revision: 16160 Added: pypy/dist/pypy/rpython/test/test_nongc.py Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/test/test_gc.py pypy/dist/pypy/rpython/memory/test/test_support.py pypy/dist/pypy/rpython/objectmodel.py Log: moved free_non_gc_object to objectmodel.py Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Fri Aug 19 14:13:27 2005 @@ -1,24 +1,14 @@ from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL from pypy.rpython.memory.support import AddressLinkedList -from pypy.rpython import lltype from pypy.rpython.memory import lltypesimulation +from pypy.rpython import lltype +from pypy.rpython.objectmodel import free_non_gc_object + import struct class GCError(Exception): pass -class FREED_OBJECT(object): - def __getattribute__(self, attr): - raise GCError("trying to access freed object") - def __setattribute__(self, attr, value): - raise GCError("trying to access freed object") - - -def free_non_gc_object(obj): - assert getattr(obj.__class__, "_alloc_flavor_", False) == "", "trying to free regular object" - obj.__dict__ = {} - obj.__class__ = FREED_OBJECT - class MarkSweepGC(object): _alloc_flavor_ = "" Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 19 14:13:27 2005 @@ -3,13 +3,14 @@ from pypy.annotation import model as annmodel from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython.rtyper import RPythonTyper -from pypy.rpython.memory.gc import free_non_gc_object, GCError, MarkSweepGC +from pypy.rpython.memory.gc import GCError, MarkSweepGC from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL from pypy.rpython.memory.simulator import MemorySimulatorError from pypy.rpython.memory import gclltype from pypy.rpython.memory.test.test_llinterpsim import interpret from pypy.rpython.memory.lladdress import simulator +from pypy.rpython.objectmodel import free_non_gc_object def setup_module(mod): mod.logstate = py.log._getstate() @@ -20,47 +21,6 @@ def teardown_module(mod): gclltype.prepare_graphs_and_create_gc = gclltype.create_no_gc -def test_free_non_gc_object(): - class TestClass(object): - _alloc_flavor_ = "" - def __init__(self, a): - self.a = a - def method1(self): - return self.a - def method2(self): - return 42 - class TestClass2(object): - pass - t = TestClass(1) - assert t.method1() == 1 - assert t.method2() == 42 - free_non_gc_object(t) - py.test.raises(GCError, "t.method1()") - py.test.raises(GCError, "t.method2()") - py.test.raises(GCError, "t.a") - py.test.raises(AssertionError, "free_non_gc_object(TestClass2())") - -def DONOTtest_rtype_free_non_gc_object(): - class TestClass(object): - _alloc_flavor_ = "" - def __init__(self, a): - self.a = a - def method1(self): - return self.a - def method2(self): - return 42 - def malloc_and_free(a): - ci = TestClass(a) - b = ci.a - free_non_gc_object(ci) - return b - a = RPythonAnnotator() - #does not raise: - s = a.build_types(malloc_and_free, [annmodel.SomeAddress()]) - assert isinstance(s, annmodel.SomeAddress) - rtyper = RPythonTyper(a) - rtyper.specialize() - class PseudoObjectModel(object): """Object model for testing purposes: you can specify roots and a layout_mapping which is a dictionary of typeids to a list of offsets of Modified: pypy/dist/pypy/rpython/memory/test/test_support.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_support.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_support.py Fri Aug 19 14:13:27 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.memory.gc import free_non_gc_object +from pypy.rpython.objectmodel import free_non_gc_object from pypy.rpython.memory.support import AddressLinkedList from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Fri Aug 19 14:13:27 2005 @@ -16,3 +16,16 @@ def we_are_translated(): return False # annotation -> True + + +class FREED_OBJECT(object): + def __getattribute__(self, attr): + raise RuntimeError("trying to access freed object") + def __setattribute__(self, attr, value): + raise RuntimeError("trying to access freed object") + + +def free_non_gc_object(obj): + assert getattr(obj.__class__, "_alloc_flavor_", False) == "", "trying to free regular object" + obj.__dict__ = {} + obj.__class__ = FREED_OBJECT Added: pypy/dist/pypy/rpython/test/test_nongc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/test/test_nongc.py Fri Aug 19 14:13:27 2005 @@ -0,0 +1,47 @@ +import py + +from pypy.annotation import model as annmodel +from pypy.translator.annrpython import RPythonAnnotator +from pypy.rpython.rtyper import RPythonTyper +from pypy.rpython.objectmodel import free_non_gc_object + +def test_free_non_gc_object(): + class TestClass(object): + _alloc_flavor_ = "" + def __init__(self, a): + self.a = a + def method1(self): + return self.a + def method2(self): + return 42 + class TestClass2(object): + pass + t = TestClass(1) + assert t.method1() == 1 + assert t.method2() == 42 + free_non_gc_object(t) + py.test.raises(RuntimeError, "t.method1()") + py.test.raises(RuntimeError, "t.method2()") + py.test.raises(RuntimeError, "t.a") + py.test.raises(AssertionError, "free_non_gc_object(TestClass2())") + +def DONOTtest_rtype_free_non_gc_object(): + class TestClass(object): + _alloc_flavor_ = "" + def __init__(self, a): + self.a = a + def method1(self): + return self.a + def method2(self): + return 42 + def malloc_and_free(a): + ci = TestClass(a) + b = ci.a + free_non_gc_object(ci) + return b + a = RPythonAnnotator() + #does not raise: + s = a.build_types(malloc_and_free, [annmodel.SomeAddress()]) + assert isinstance(s, annmodel.SomeAddress) + rtyper = RPythonTyper(a) + rtyper.specialize() From cfbolz at codespeak.net Fri Aug 19 15:41:34 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 15:41:34 +0200 (CEST) Subject: [pypy-svn] r16161 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050819134134.3028927B68@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 15:41:33 2005 New Revision: 16161 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Log: convertlltype does now not need to know anything about the memory layout of structs + arrays any more. instead it uses simulatorptr. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Fri Aug 19 15:41:33 2005 @@ -1,22 +1,18 @@ from pypy.rpython.memory import lladdress from pypy.rpython.memory.lltypesimulation import simulatorptr, sizeof -from pypy.rpython.memory.lltypesimulation import get_fixed_size -from pypy.rpython.memory.lltypesimulation import get_variable_size -from pypy.rpython.memory.lltypesimulation import primitive_to_fmt -from pypy.rpython.memory.lltypesimulation import get_layout +from pypy.rpython.memory.lltypesimulation import nullptr, malloc +from pypy.rpython.memory.lltypesimulation import init_object_on_address from pypy.objspace.flow.model import traverse, Link, Constant, Block from pypy.objspace.flow.model import Constant from pypy.rpython import lltype from pypy.rpython.rmodel import IntegerRepr -import types, struct +import types FUNCTIONTYPES = (types.FunctionType, types.UnboundMethodType, types.BuiltinFunctionType) -INT_SIZE = struct.calcsize("i") - class LLTypeConverter(object): def __init__(self, address, gc=None): self.type_to_typeid = {} @@ -34,107 +30,107 @@ typeid = self.type_to_typeid[TYPE] return typeid - def convert(self, val_or_ptr, inline_to_addr=None, from_parent=False): + def convert(self, val_or_ptr, inline_to_ptr=None): TYPE = lltype.typeOf(val_or_ptr) if isinstance(TYPE, lltype.Primitive): - if inline_to_addr is not None and TYPE != lltype.Void: - inline_to_addr._store(primitive_to_fmt[TYPE], val_or_ptr) + assert inline_to_ptr is None return val_or_ptr elif isinstance(TYPE, lltype.Array): - return self.convert_array(val_or_ptr, inline_to_addr, from_parent) + return self.convert_array(val_or_ptr, inline_to_ptr) elif isinstance(TYPE, lltype.Struct): - return self.convert_struct(val_or_ptr, inline_to_addr, from_parent) + return self.convert_struct(val_or_ptr, inline_to_ptr) elif isinstance(TYPE, lltype.Ptr): - return self.convert_pointer(val_or_ptr, inline_to_addr, from_parent) + return self.convert_pointer(val_or_ptr, inline_to_ptr) elif isinstance(TYPE, lltype.OpaqueType): - return self.convert_object(val_or_ptr, inline_to_addr, from_parent) + return self.convert_object(val_or_ptr, inline_to_ptr) elif isinstance(TYPE, lltype.FuncType): - return self.convert_object(val_or_ptr, inline_to_addr, from_parent) + return self.convert_object(val_or_ptr, inline_to_ptr) elif isinstance(TYPE, lltype.PyObjectType): - return self.convert_object(val_or_ptr, inline_to_addr, from_parent) + return self.convert_object(val_or_ptr, inline_to_ptr) else: assert 0, "don't know about %s" % (val_or_ptr, ) - def convert_array(self, _array, inline_to_addr, from_parent): + def convert_array(self, _array, inline_to_ptr): if _array in self.converted: - address = self.converted[_array] - assert inline_to_addr is None or address == inline_to_addr - return address + ptr = self.converted[_array] + assert inline_to_ptr is None or ptr == inline_to_ptr + return ptr TYPE = lltype.typeOf(_array) arraylength = len(_array.items) size = sizeof(TYPE, arraylength) - if inline_to_addr is not None: - startaddr = inline_to_addr + if inline_to_ptr is not None: + ptr = inline_to_ptr else: startaddr = self.curraddress if self.gc is not None: self.gc.init_gc_object(startaddr, self.get_typeid(TYPE)) startaddr += self.gc.size_gc_header() - self.constantroots.append( - simulatorptr(lltype.Ptr(TYPE), startaddr)) self.curraddress += size if self.gc is not None: self.curraddress += self.gc.size_gc_header() - self.converted[_array] = startaddr - startaddr.signed[0] = arraylength - curraddr = startaddr + get_fixed_size(TYPE) - varsize = get_variable_size(TYPE) - for item in _array.items: - self.convert(item, curraddr, from_parent=True) - curraddr += varsize - return startaddr + ptr = init_object_on_address(startaddr, TYPE, arraylength) + self.constantroots.append(ptr) + self.converted[_array] = ptr + if isinstance(TYPE.OF, lltype.Struct): + for i, item in enumerate(_array.items): + self.convert(item, ptr[i]) + else: + for i, item in enumerate(_array.items): + ptr[i] = self.convert(item) + return ptr - def convert_struct(self, _struct, inline_to_addr, from_parent): + def convert_struct(self, _struct, inline_to_ptr): if _struct in self.converted: - address = self.converted[_struct] - assert inline_to_addr is None or address == inline_to_addr - return address + ptr = self.converted[_struct] + assert inline_to_ptr is None or ptr == inline_to_ptr + return ptr parent = _struct._parentstructure() - if parent is not None and not from_parent: - address = self.convert(parent) - layout = get_layout(lltype.typeOf(parent)) - return address + layout[_struct._parent_index] + if parent is not None and inline_to_ptr is None: + ptr = self.convert(parent) + if isinstance(_struct._parent_index, str): + return getattr(ptr, _struct._parent_index) + else: + return ptr[_struct._parent_index] TYPE = lltype.typeOf(_struct) - layout = get_layout(TYPE) if TYPE._arrayfld is not None: inlinedarraylength = len(getattr(_struct, TYPE._arrayfld).items) size = sizeof(TYPE, inlinedarraylength) else: + inlinedarraylength = None size = sizeof(TYPE) - if inline_to_addr is not None: - startaddr = inline_to_addr + if inline_to_ptr is not None: + ptr = inline_to_ptr else: startaddr = self.curraddress if self.gc is not None: self.gc.init_gc_object(startaddr, self.get_typeid(TYPE)) startaddr += self.gc.size_gc_header() - self.constantroots.append( - simulatorptr(lltype.Ptr(TYPE), startaddr)) self.curraddress += size if self.gc is not None: self.curraddress += self.gc.size_gc_header() - self.converted[_struct] = startaddr + ptr = init_object_on_address(startaddr, TYPE, inlinedarraylength) + self.constantroots.append(ptr) + self.converted[_struct] = ptr for name in TYPE._flds: - addr = startaddr + layout[name] - self.convert(getattr(_struct, name), addr, from_parent=True) - return startaddr + FIELD = getattr(TYPE, name) + if isinstance(FIELD, (lltype.Struct, lltype.Array)): + self.convert(getattr(_struct, name), getattr(ptr, name)) + else: + setattr(ptr, name, self.convert(getattr(_struct, name))) + return ptr - def convert_pointer(self, _ptr, inline_to_addr, from_parent): + def convert_pointer(self, _ptr, inline_to_ptr): + assert inline_to_ptr is None, "can't inline pointer" TYPE = lltype.typeOf(_ptr) if _ptr._obj is not None: - addr = self.convert(_ptr._obj) + return self.convert(_ptr._obj) else: - addr = lladdress.NULL - assert isinstance(addr, lladdress.address) - if inline_to_addr is not None: - inline_to_addr.address[0] = addr - return simulatorptr(TYPE, addr) - - def convert_object(self, _obj, inline_to_addr, from_parent): - if inline_to_addr is not None: - assert 0, "can't inline function or pyobject" - else: - return lladdress.get_address_of_object(_obj) + return nullptr(TYPE.TO) + + def convert_object(self, _obj, inline_to_ptr): + assert inline_to_ptr is None, "can't inline function or pyobject" + return simulatorptr(lltype.Ptr(lltype.typeOf(_obj)), + lladdress.get_address_of_object(_obj)) class FlowGraphConstantConverter(object): def __init__(self, flowgraphs, gc=None): @@ -213,11 +209,11 @@ for name in TYPE._flds: candidates.append(getattr(cand, name)) elif isinstance(cand, lltype._opaque): - total_size += struct.calcsize("i") + total_size += sizeof(lltype.Signed) elif isinstance(cand, lltype._func): - total_size += struct.calcsize("i") + total_size += sizeof(lltype.Signed) elif isinstance(cand, lltype._pyobject): - total_size += struct.calcsize("i") + total_size += sizeof(lltype.Signed) else: assert 0, "don't know about %s %s" % (cand, cand.__class__) self.total_size = total_size Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Fri Aug 19 15:41:33 2005 @@ -64,8 +64,6 @@ typeid = self.objectmodel.get_typeid(TYPE) address = self.gc.malloc(typeid, lltypesimulation.sizeof(TYPE, size)) - result = lltypesimulation.simulatorptr(lltype.Ptr(TYPE), address) - result._zero_initialize(size) - result._init_size(size) + return lltypesimulation.init_object_on_address(address, TYPE, size) self.objectmodel.update_changed_addresses() return result Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Fri Aug 19 15:41:33 2005 @@ -303,6 +303,9 @@ else: size = fixedsize + n * varsize address = lladdress.raw_malloc(size) + return init_object_on_address(address, T, n) + +def init_object_on_address(address, T, n=None): result = simulatorptr(lltype.Ptr(T), address) result._zero_initialize(n) result._init_size(n) Modified: pypy/dist/pypy/rpython/memory/test/test_convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_convertlltype.py Fri Aug 19 15:41:33 2005 @@ -8,10 +8,6 @@ c = cvter.convert("c") assert c1 == 1 assert c == "c" - cvter.convert(10, addr) - assert addr.signed[0] == 10 - cvter.convert("c", addr) - assert addr.char[0] == "c" def test_convert_array_of_primitives(): cvter = LLTypeConverter(lladdress.raw_malloc(1000)) From cfbolz at codespeak.net Fri Aug 19 16:06:04 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 16:06:04 +0200 (CEST) Subject: [pypy-svn] r16163 - pypy/dist/pypy/rpython/memory Message-ID: <20050819140604.EB97B27B6C@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 16:06:04 2005 New Revision: 16163 Added: pypy/dist/pypy/rpython/memory/lltypelayout.py Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py Log: move all the layout information to a lltypelayout. To be done: make the output of the functions there a bit more generally usable. Added: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Fri Aug 19 16:06:04 2005 @@ -0,0 +1,88 @@ +from pypy.rpython import lltype +from pypy.rpython.memory import lladdress + +import struct + +primitive_to_fmt = {lltype.Signed: "i", + lltype.Unsigned: "I", + lltype.Char: "c", + lltype.Bool: "B", + lladdress.Address: "P", + } + + +#___________________________________________________________________________ +# Utility functions that know about the memory layout of the lltypes +# in the simulation + +#returns some sort of layout information that is useful for the simulatorptr +def get_layout(TYPE): + layout = {} + if isinstance(TYPE, lltype.Primitive): + return primitive_to_fmt[TYPE] + elif isinstance(TYPE, lltype.Ptr): + return "P" + elif isinstance(TYPE, lltype.Struct): + curr = 0 + for name in TYPE._names: + layout[name] = curr + curr += get_fixed_size(TYPE._flds[name]) + layout["_size"] = curr + return layout + elif isinstance(TYPE, lltype.Array): + return (get_fixed_size(lltype.Signed), get_fixed_size(TYPE.OF)) + elif isinstance(TYPE, lltype.OpaqueType): + return "i" + elif isinstance(TYPE, lltype.FuncType): + return "i" + elif isinstance(TYPE, lltype.PyObjectType): + return "i" + else: + assert 0, "type %s not yet implemented" % (TYPE, ) + +def get_fixed_size(TYPE): + if isinstance(TYPE, lltype.Primitive): + if TYPE == lltype.Void: + return 0 + return struct.calcsize(primitive_to_fmt[TYPE]) + elif isinstance(TYPE, lltype.Ptr): + return struct.calcsize("P") + elif isinstance(TYPE, lltype.Struct): + return get_layout(TYPE)["_size"] + elif isinstance(TYPE, lltype.Array): + return get_fixed_size(lltype.Unsigned) + elif isinstance(TYPE, lltype.OpaqueType): + return get_fixed_size(lltype.Unsigned) + elif isinstance(TYPE, lltype.FuncType): + return get_fixed_size(lltype.Unsigned) + elif isinstance(TYPE, lltype.PyObjectType): + return get_fixed_size(lltype.Unsigned) + assert 0, "not yet implemented" + +def get_variable_size(TYPE): + if isinstance(TYPE, lltype.Array): + return get_fixed_size(TYPE.OF) + elif isinstance(TYPE, lltype.Primitive): + return 0 + elif isinstance(TYPE, lltype.Struct): + if TYPE._arrayfld is not None: + return get_variable_size(TYPE._flds[TYPE._arrayfld]) + else: + return 0 + elif isinstance(TYPE, lltype.OpaqueType): + return 0 + elif isinstance(TYPE, lltype.FuncType): + return 0 + elif isinstance(TYPE, lltype.PyObjectType): + return 0 + else: + assert 0, "not yet implemented" + +def sizeof(TYPE, i=None): + fixedsize = get_fixed_size(TYPE) + varsize = get_variable_size(TYPE) + if i is None: + assert varsize == 0 + return fixedsize + else: + return fixedsize + i * varsize Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Fri Aug 19 16:06:04 2005 @@ -1,96 +1,13 @@ import py +from pypy.rpython.memory.lltypelayout import get_layout, get_fixed_size +from pypy.rpython.memory.lltypelayout import get_variable_size, sizeof +from pypy.rpython.memory.lltypelayout import primitive_to_fmt from pypy.rpython.memory import lladdress from pypy.rpython import lltype -import struct - log = py.log.Producer("lltypesim") -primitive_to_fmt = {lltype.Signed: "i", - lltype.Unsigned: "I", - lltype.Char: "c", - lltype.Bool: "B", - } - -INT_SIZE = struct.calcsize("i") - -#___________________________________________________________________________ -# Utility functions that know about the memory layout of the lltypes -# in the simulation - -#returns some sort of layout information that is useful for the simulatorptr -def get_layout(TYPE): - layout = {} - if isinstance(TYPE, lltype.Primitive): - return primitive_to_fmt[TYPE] - elif isinstance(TYPE, lltype.Ptr): - return "P" - elif isinstance(TYPE, lltype.Struct): - curr = 0 - for name in TYPE._names: - layout[name] = curr - curr += get_fixed_size(TYPE._flds[name]) - layout["_size"] = curr - return layout - elif isinstance(TYPE, lltype.Array): - return (get_fixed_size(lltype.Signed), get_fixed_size(TYPE.OF)) - elif isinstance(TYPE, lltype.OpaqueType): - return "i" - elif isinstance(TYPE, lltype.FuncType): - return "i" - elif isinstance(TYPE, lltype.PyObjectType): - return "i" - else: - assert 0, "type %s not yet implemented" % (TYPE, ) - -def get_fixed_size(TYPE): - if isinstance(TYPE, lltype.Primitive): - if TYPE == lltype.Void: - return 0 - return struct.calcsize(primitive_to_fmt[TYPE]) - elif isinstance(TYPE, lltype.Ptr): - return struct.calcsize("P") - elif isinstance(TYPE, lltype.Struct): - return get_layout(TYPE)["_size"] - elif isinstance(TYPE, lltype.Array): - return get_fixed_size(lltype.Unsigned) - elif isinstance(TYPE, lltype.OpaqueType): - return get_fixed_size(lltype.Unsigned) - elif isinstance(TYPE, lltype.FuncType): - return get_fixed_size(lltype.Unsigned) - elif isinstance(TYPE, lltype.PyObjectType): - return get_fixed_size(lltype.Unsigned) - assert 0, "not yet implemented" - -def get_variable_size(TYPE): - if isinstance(TYPE, lltype.Array): - return get_fixed_size(TYPE.OF) - elif isinstance(TYPE, lltype.Primitive): - return 0 - elif isinstance(TYPE, lltype.Struct): - if TYPE._arrayfld is not None: - return get_variable_size(TYPE._flds[TYPE._arrayfld]) - else: - return 0 - elif isinstance(TYPE, lltype.OpaqueType): - return 0 - elif isinstance(TYPE, lltype.FuncType): - return 0 - elif isinstance(TYPE, lltype.PyObjectType): - return 0 - else: - assert 0, "not yet implemented" - -def sizeof(TYPE, i=None): - fixedsize = get_fixed_size(TYPE) - varsize = get_variable_size(TYPE) - if i is None: - assert varsize == 0 - return fixedsize - else: - return fixedsize + i * varsize - def _expose(T, address): """XXX A nice docstring here""" From ale at codespeak.net Fri Aug 19 16:26:56 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 19 Aug 2005 16:26:56 +0200 (CEST) Subject: [pypy-svn] r16164 - pypy/dist/pypy/objspace/std Message-ID: <20050819142656.7C22C27B7A@code1.codespeak.net> Author: ale Date: Fri Aug 19 16:26:55 2005 New Revision: 16164 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py Log: UnicodEncodeError takes exactly 5 arguments. changed the repr to be more carefull with quotes. I am not sure this is enough though Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Fri Aug 19 16:26:55 2005 @@ -48,7 +48,11 @@ if 0 < uchr < 256: result[i] = chr(uchr) else: - raise OperationError(space.w_UnicodeEncodeError, space.wrap('invalid decimal Unicode string')) + w_encoding = space.wrap('decimal') + w_start = space.wrap(i) + w_end = space.wrap(i+1) + w_reason = space.wrap('invalid decimal Unicode string') + raise OperationError(space.w_UnicodeEncodeError,space.newtuple ([w_encoding, w_unistr, w_start, w_end, w_reason])) return ''.join(result) # string-to-unicode delegation @@ -884,9 +888,10 @@ hexdigits = "0123456789abcdef" chars = w_unicode._value size = len(chars) + quote = "'" result = ['\0'] * (2 + size*6 + 1) result[0] = 'u' - result[1] = "'" + result[1] = quote i = 2 for ch in chars: if ch == u'\\': @@ -894,9 +899,11 @@ i += 2 continue if ch == u"'": - result[i] = '\\' - result[i + 1] = "'" - i += 2 + quote ='''"''' + result[1] = quote + result[i] = '\'' + #result[i + 1] = "'" + i += 1 continue code = ord(ch) if code > 0x10000: @@ -948,7 +955,7 @@ continue result[i] = chr(code) i += 1 - result[i] = "'" + result[i] = quote i += 1 return space.wrap(''.join(result[:i])) From ale at codespeak.net Fri Aug 19 16:32:45 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 19 Aug 2005 16:32:45 +0200 (CEST) Subject: [pypy-svn] r16165 - pypy/dist/pypy/module/_codecs Message-ID: <20050819143245.952D027B7A@code1.codespeak.net> Author: ale Date: Fri Aug 19 16:32:44 2005 New Revision: 16165 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: corrected utf-16 decoding (should be called with byteorder = 'native' added 'final' to the signature (not used) Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Fri Aug 19 16:32:44 2005 @@ -274,7 +274,7 @@ res = u''.join(p) return res, len(res) -def utf_16_ex_decode( data,errors='strict'): +def utf_16_ex_decode( data,errors='strict',final = True): """None """ res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'native') @@ -368,7 +368,7 @@ def utf_16_encode( obj,errors='strict'): """None """ - res = PyUnicode_EncodeUTF16(obj,len(obj),errors) + res = PyUnicode_EncodeUTF16(obj,len(obj),errors,'native') res = ''.join(res) return res, len(res) @@ -400,14 +400,14 @@ res = ''.join(res) return res, len(res) -def utf_16_le_decode( data,errors='strict'): +def utf_16_le_decode( data,errors='strict',final = True): """None """ res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little') res = ''.join(res) return res, len(res) -def utf_16_be_decode( data,errors='strict'): +def utf_16_be_decode( data,errors='strict',final = True): """None """ res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big') @@ -1332,6 +1332,7 @@ return res hexdigits = [hex(i)[-1] for i in range(16)]+[hex(i)[-1].upper() for i in range(10,16)] + def hexescape(s,pos,digits,message,errors): chr = 0 p = [] From nik at codespeak.net Fri Aug 19 17:43:30 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 19 Aug 2005 17:43:30 +0200 (CEST) Subject: [pypy-svn] r16166 - pypy/dist/pypy/module/_sre Message-ID: <20050819154330.78AC427B7A@code1.codespeak.net> Author: nik Date: Fri Aug 19 17:43:29 2005 New Revision: 16166 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved State class from app-level to interp-level. don't look too closely it's very ugly during the transition phase. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Fri Aug 19 17:43:29 2005 @@ -18,6 +18,7 @@ interpleveldefs = { 'getlower': 'interp_sre.getlower', + '_State': 'interp_sre.make_state', '_check_charset': 'interp_sre.check_charset', '_at_dispatch': 'interp_sre.at_dispatch', '_category_dispatch': 'interp_sre.category_dispatch', Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 19 17:43:29 2005 @@ -35,7 +35,7 @@ """If zero or more characters at the beginning of string match this regular expression, return a corresponding MatchObject instance. Return None if the string does not match the pattern.""" - state = _State(string, pos, endpos, self.flags) + state = _sre._State(string, pos, endpos, self.flags) if match(state, self._code): return SRE_Match(self, state) else: @@ -46,7 +46,7 @@ expression produces a match, and return a corresponding MatchObject instance. Return None if no position in the string matches the pattern.""" - state = _State(string, pos, endpos, self.flags) + state = _sre._State(string, pos, endpos, self.flags) if search(state, self._code): return SRE_Match(self, state) else: @@ -55,7 +55,7 @@ def findall(self, string, pos=0, endpos=sys.maxint): """Return a list of all non-overlapping matches of pattern in string.""" matchlist = [] - state = _State(string, pos, endpos, self.flags) + state = _sre._State(string, pos, endpos, self.flags) while state.start <= state.end: state.reset() state.string_position = state.start @@ -79,7 +79,7 @@ # handle non-literal strings ; hand it over to the template compiler import sre filter = sre._subx(self, template) - state = _State(string, 0, sys.maxint, self.flags) + state = _sre._State(string, 0, sys.maxint, self.flags) sublist = [] n = last_pos = 0 @@ -126,7 +126,7 @@ def split(self, string, maxsplit=0): """Split string by the occurrences of pattern.""" splitlist = [] - state = _State(string, 0, sys.maxint, self.flags) + state = _sre._State(string, 0, sys.maxint, self.flags) n = 0 last = state.start while not maxsplit or n < maxsplit: @@ -169,7 +169,7 @@ def __init__(self, pattern, string, start, end): self.pattern = pattern - self._state = _State(string, start, end, self.pattern.flags) + self._state = _sre._State(string, start, end, self.pattern.flags) def _match_search(self, matcher): state = self._state @@ -201,7 +201,7 @@ self.lastindex = state.lastindex if self.lastindex < 0: self.lastindex = None - self.regs = self._create_regs(state) + self.regs = state.create_regs(self.re.groups) if pattern._indexgroup and 0 <= self.lastindex < len(pattern._indexgroup): # The above upper-bound check should not be necessary, as the re # compiler is supposed to always provide an _indexgroup list long @@ -212,19 +212,6 @@ else: self.lastgroup = None - def _create_regs(self, state): - """Creates a tuple of index pairs representing matched groups.""" - regs = [(state.start, state.string_position)] - for group in range(self.re.groups): - mark_index = 2 * group - if mark_index + 1 < len(state.marks) \ - and state.marks[mark_index] is not None \ - and state.marks[mark_index + 1] is not None: - regs.append((state.marks[mark_index], state.marks[mark_index + 1])) - else: - regs.append((-1, -1)) - return tuple(regs) - def _get_index(self, group): if isinstance(group, int): if group >= 0 and group <= self.re.groups: @@ -304,57 +291,50 @@ raise TypeError, "cannot copy this pattern object" -class _State(object): +class _MatchContext(object): - def __init__(self, string, start, end, flags): - self.string = string - if start < 0: - start = 0 - if end > len(string): - end = len(string) - self.start = start - self.string_position = self.start - self.end = end - self.pos = start - self.flags = flags - self.reset() - - def reset(self): - self.marks = [] - self.lastindex = -1 - self.marks_stack = [] - self.context_stack = [] - self.repeat = None - - def set_mark(self, mark_nr, position): - if mark_nr & 1: - # This id marks the end of a group. - self.lastindex = mark_nr / 2 + 1 - if mark_nr >= len(self.marks): - self.marks.extend([None] * (mark_nr - len(self.marks) + 1)) - self.marks[mark_nr] = position - - def get_marks(self, group_index): - marks_index = 2 * group_index - if len(self.marks) > marks_index + 1: - return self.marks[marks_index], self.marks[marks_index + 1] - else: - return None, None + def __init__(self, state, pattern_codes): + self.state = state + self.pattern_codes = pattern_codes + self.string_position = state.string_position + self.code_position = 0 + self.has_matched = None - def marks_push(self): - self.marks_stack.append((self.marks[:], self.lastindex)) + def push_new_context(self, pattern_offset): + """Creates a new child context of this context and pushes it on the + stack. pattern_offset is the offset off the current code position to + start interpreting from.""" + child_context = _MatchContext(self.state, + self.pattern_codes[self.code_position + pattern_offset:]) + self.state.context_stack.append(child_context) + return child_context - def marks_pop(self): - self.marks, self.lastindex = self.marks_stack.pop() + def peek_char(self, peek=0): + return self.state.string[self.string_position + peek] - def marks_pop_keep(self): - self.marks, self.lastindex = self.marks_stack[-1] + def skip_char(self, skip_count): + self.string_position += skip_count + + def remaining_chars(self): + return self.state.end - self.string_position + + def peek_code(self, peek=0): + return self.pattern_codes[self.code_position + peek] + + def skip_code(self, skip_count): + self.code_position += skip_count - def marks_pop_discard(self): - self.marks_stack.pop() + def remaining_codes(self): + return len(self.pattern_codes) - self.code_position + + def at_beginning(self): + return self.string_position == 0 + + def at_end(self): + return self.string_position == self.state.end - def lower(self, char_ord): - return _sre.getlower(char_ord, self.flags) + def at_linebreak(self): + return not self.at_end() and self.peek_char() == "\n" def search(state, pattern_codes): @@ -368,6 +348,7 @@ pattern_codes = pattern_codes[pattern_codes[1] + 1:] string_position = state.start + """ if pattern_codes[0] == OPCODES["literal"]: # Special case: Pattern starts with a literal character. This is # used for short prefixes @@ -386,6 +367,7 @@ if match(state, pattern_codes[2:]): return True return False + """ # General case while string_position <= state.end: @@ -454,49 +436,6 @@ return has_matched -class _MatchContext(object): - - def __init__(self, state, pattern_codes): - self.state = state - self.pattern_codes = pattern_codes - self.string_position = state.string_position - self.code_position = 0 - self.has_matched = None - - def push_new_context(self, pattern_offset): - """Creates a new child context of this context and pushes it on the - stack. pattern_offset is the offset off the current code position to - start interpreting from.""" - child_context = _MatchContext(self.state, - self.pattern_codes[self.code_position + pattern_offset:]) - self.state.context_stack.append(child_context) - return child_context - - def peek_char(self, peek=0): - return self.state.string[self.string_position + peek] - - def skip_char(self, skip_count): - self.string_position += skip_count - - def remaining_chars(self): - return self.state.end - self.string_position - - def peek_code(self, peek=0): - return self.pattern_codes[self.code_position + peek] - - def skip_code(self, skip_count): - self.code_position += skip_count - - def remaining_codes(self): - return len(self.pattern_codes) - self.code_position - - def at_end(self): - return self.string_position == self.state.end - - def at_linebreak(self): - return not self.at_end() and self.peek_char() == "\n" - - class _RepeatContext(_MatchContext): def __init__(self, context): Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 19 17:43:29 2005 @@ -1,7 +1,9 @@ -from pypy.interpreter.baseobjspace import ObjSpace +from pypy.interpreter.baseobjspace import ObjSpace, Wrappable # XXX is it allowed to import app-level module like this? from pypy.module._sre.app_info import CODESIZE from pypy.module.array.app_array import array +from pypy.interpreter.typedef import GetSetProperty, TypeDef +from pypy.interpreter.gateway import interp2app #### Exposed functions @@ -20,6 +22,113 @@ else: return space.wrap(char_ord) +#### Core classes + +# XXX the wrapped/unwrapped semantics of the following classes are currently +# very confusing because they are still used at app-level. + +def make_state(space, w_string, w_start, w_end, w_flags): + # XXX Uhm, temporary + return space.wrap(W_State(space, w_string, w_start, w_end, w_flags)) + +class W_State(Wrappable): + + def __init__(self, space, w_string, w_start, w_end, w_flags): + self.space = space + self.w_string = w_string + start = space.int_w(w_start) + end = space.int_w(w_end) + if start < 0: + start = 0 + if end > space.int_w(space.len(w_string)): + end = space.int_w(space.len(w_string)) + self.start = start + self.string_position = start + self.end = end + self.pos = start + self.flags = space.int_w(w_flags) + self.reset() + + def reset(self): + self.marks = [] + self.lastindex = -1 + self.marks_stack = [] + self.context_stack = self.space.newlist([]) + self.w_repeat = self.space.w_None + + def set_mark(self, w_mark_nr, w_position): + mark_nr = self.space.int_w(w_mark_nr) + if mark_nr & 1: + # This id marks the end of a group. + self.lastindex = mark_nr / 2 + 1 + if mark_nr >= len(self.marks): + self.marks.extend([None] * (mark_nr - len(self.marks) + 1)) + self.marks[mark_nr] = self.space.int_w(w_position) + + def get_marks(self, w_group_index): + marks_index = 2 * self.space.int_w(w_group_index) + if len(self.marks) > marks_index + 1: + return self.space.newtuple([self.space.wrap(self.marks[marks_index]), + self.space.wrap(self.marks[marks_index + 1])]) + else: + return self.space.newtuple([self.space.w_None, self.space.w_None]) + + def create_regs(self, w_group_count): + """Creates a tuple of index pairs representing matched groups, a format + that's convenient for SRE_Match.""" + regs = [self.space.newtuple([self.space.wrap(self.start), self.space.wrap(self.string_position)])] + for group in range(self.space.int_w(w_group_count)): + mark_index = 2 * group + if mark_index + 1 < len(self.marks) \ + and self.marks[mark_index] is not None \ + and self.marks[mark_index + 1] is not None: + regs.append(self.space.newtuple([self.space.wrap(self.marks[mark_index]), + self.space.wrap(self.marks[mark_index + 1])])) + else: + regs.append(self.space.newtuple([self.space.wrap(-1), + self.space.wrap(-1)])) + return self.space.newtuple(regs) + + def marks_push(self): + self.marks_stack.append((self.marks[:], self.lastindex)) + + def marks_pop(self): + self.marks, self.lastindex = self.marks_stack.pop() + + def marks_pop_keep(self): + self.marks, self.lastindex = self.marks_stack[-1] + + def marks_pop_discard(self): + self.marks_stack.pop() + + def lower(self, w_char_ord): + return getlower(self.space, w_char_ord, self.space.wrap(self.flags)) + +W_State.typedef = TypeDef("W_State", + string = GetSetProperty(lambda space, state: state.w_string, + lambda space, state, value: setattr(state, "w_string", value)), + start = GetSetProperty(lambda space, state: space.wrap(state.start), + lambda space, state, value: setattr(state, "start", space.int_w(value))), + end = GetSetProperty(lambda space, state: space.wrap(state.end)), + string_position = GetSetProperty(lambda space, state: space.wrap(state.string_position), + lambda space, state, value: setattr(state, "string_position", space.int_w(value))), + pos = GetSetProperty(lambda space, state: space.wrap(state.pos)), + lastindex = GetSetProperty(lambda space, state: space.wrap(state.lastindex)), + context_stack = GetSetProperty(lambda space, state: state.context_stack), + repeat = GetSetProperty(lambda space, state: state.w_repeat, + lambda space, state, value: setattr(state, "w_repeat", value)), + reset = interp2app(W_State.reset, unwrap_spec = ["self"]), + set_mark = interp2app(W_State.set_mark), + get_marks = interp2app(W_State.get_marks), + create_regs = interp2app(W_State.create_regs), + marks_push = interp2app(W_State.marks_push, unwrap_spec = ["self"]), + marks_pop = interp2app(W_State.marks_pop, unwrap_spec = ["self"]), + marks_pop_keep = interp2app(W_State.marks_pop_keep, unwrap_spec = ["self"]), + marks_pop_discard = interp2app(W_State.marks_pop_discard, unwrap_spec = ["self"]), + lower = interp2app(W_State.lower), +) + + #### Category helpers ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, From ale at codespeak.net Fri Aug 19 17:55:04 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 19 Aug 2005 17:55:04 +0200 (CEST) Subject: [pypy-svn] r16167 - pypy/dist/pypy/objspace/std Message-ID: <20050819155504.B661527B7A@code1.codespeak.net> Author: ale Date: Fri Aug 19 17:55:03 2005 New Revision: 16167 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py Log: I think the quoting in unicode repr is correct now Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Fri Aug 19 17:55:03 2005 @@ -888,23 +888,34 @@ hexdigits = "0123456789abcdef" chars = w_unicode._value size = len(chars) - quote = "'" + + singlequote = doublequote = False + for c in chars: + if c == u'\'': + singlequote = True + elif c == u'"': + doublequote = True + if singlequote and not doublequote: + quote = '"' + else: + quote = '\'' result = ['\0'] * (2 + size*6 + 1) result[0] = 'u' result[1] = quote i = 2 for ch in chars: - if ch == u'\\': - result[i] = result[i + 1] = '\\' + if ch == u'\\' or ch == str(quote) : + result[i] = '\\' + result[i + 1] = str(ch) i += 2 continue - if ch == u"'": - quote ='''"''' - result[1] = quote - result[i] = '\'' - #result[i + 1] = "'" - i += 1 - continue +## if ch == u"'": +## quote ='''"''' +## result[1] = quote +## result[i] = '\'' +## #result[i + 1] = "'" +## i += 1 +## continue code = ord(ch) if code > 0x10000: # Resize if needed From ale at codespeak.net Fri Aug 19 18:38:39 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 19 Aug 2005 18:38:39 +0200 (CEST) Subject: [pypy-svn] r16168 - pypy/dist/pypy/lib Message-ID: <20050819163839.8169527B6C@code1.codespeak.net> Author: ale Date: Fri Aug 19 18:38:38 2005 New Revision: 16168 Modified: pypy/dist/pypy/lib/_formatting.py Log: Added support for using __unicode__ methods in _formating Modified: pypy/dist/pypy/lib/_formatting.py ============================================================================== --- pypy/dist/pypy/lib/_formatting.py (original) +++ pypy/dist/pypy/lib/_formatting.py Fri Aug 19 18:38:38 2005 @@ -396,6 +396,8 @@ def format(self): if isinstance(self.value, unicode): return self.std_wp(self.value) + if hasattr(self.value,'__unicode__'): + return self.std_wp(self.value.__unicode__()) return self.std_wp(str(self.value)) class UnicodeCharFormatter(Formatter): From cfbolz at codespeak.net Fri Aug 19 18:52:18 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 18:52:18 +0200 (CEST) Subject: [pypy-svn] r16169 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050819165218.D95A327B6C@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 18:52:17 2005 New Revision: 16169 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/lltypelayout.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: Moved the functionality that finds gc pointers in an object to lltypesimulation. In addition all the information the gc needs from ObjectModel are now precomputed. The idea is that the backend can somehow generate those tables as well at compile time. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Fri Aug 19 18:52:17 2005 @@ -27,6 +27,7 @@ index = len(self.types) self.type_to_typeid[TYPE] = index self.types.append(TYPE) + return index typeid = self.type_to_typeid[TYPE] return typeid @@ -140,13 +141,15 @@ self.total_size = 0 self.gc = gc - def collect_constants(self): + def collect_constants_and_types(self): constants = {} + types = {} def collect_args(args): for arg in args: if (isinstance(arg, Constant) and arg.concretetype is not lltype.Void): constants[arg] = None + types[arg.concretetype] = True def visit(obj): if isinstance(obj, Link): collect_args(obj.args) @@ -157,9 +160,12 @@ elif isinstance(obj, Block): for op in obj.operations: collect_args(op.args) + if op.opname in ("malloc", "malloc_varsize"): + types[op.args[0].value] = True for graph in self.flowgraphs.itervalues(): traverse(visit, graph) self.constants = constants + self.types = types def calculate_size(self): total_size = 0 @@ -248,8 +254,18 @@ for graph in self.flowgraphs.itervalues(): traverse(visit, graph) + def create_type_ids(self): + for TYPE in self.types: + print TYPE + if isinstance(TYPE, (lltype.Array, lltype.Struct)): + #assign a typeid + self.cvter.get_typeid(TYPE) + elif isinstance(TYPE, lltype.Ptr): + self.cvter.get_typeid(TYPE.TO) + def convert(self): - self.collect_constants() + self.collect_constants_and_types() self.calculate_size() self.convert_constants() self.patch_graphs() + self.create_type_ids() Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Fri Aug 19 18:52:17 2005 @@ -56,13 +56,24 @@ gc_info = curr - self.size_gc_header() if gc_info.signed[0] == 1: continue - pointers = self.objectmodel.get_contained_pointers( - curr, gc_info.signed[1]) - while 1: - pointer = pointers.pop() - if pointer == NULL: - break + typeid = gc_info.signed[1] + offsets = self.objectmodel.offsets_to_gc_pointers(typeid) + for i in range(len(offsets)): + pointer = curr + offsets[i] objects.append(pointer.address[0]) + i += 1 + if self.objectmodel.is_varsize(typeid): + offset = self.objectmodel.varsize_offset_to_variable_part( + typeid) + length = (curr + self.objectmodel.varsize_offset_to_length(typeid)).signed[0] + offsets = self.objectmodel.varsize_offsets_to_gcpointers_in_var_part(typeid) + itemlength = self.objectmodel.varsize_item_sizes(typeid) + curr += offset + i = 0 + for i in range(length): + item = curr + itemlength * i + for j in range(len(offsets)): + objects.append((item + offsets[j]).address[0]) gc_info.signed[0] = 1 newmo = AddressLinkedList() while 1: #sweep @@ -80,7 +91,6 @@ def size_gc_header(self): return lltypesimulation.sizeof(lltype.Signed) * 2 - def init_gc_object(self, addr, typeid): addr.signed[0] = 0 addr.signed[1] = typeid Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Fri Aug 19 18:52:17 2005 @@ -1,17 +1,49 @@ from pypy.rpython import lltype from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL +from pypy.rpython.memory import lltypelayout from pypy.rpython.memory import lltypesimulation from pypy.rpython.memory.gc import MarkSweepGC class LLInterpObjectModel(object): - def __init__(self, llinterp, types, type_to_typeid, constantroots): - self.types = types + def __init__(self, llinterp, types, + type_to_typeid, constantroots): self.type_to_typeid = type_to_typeid self.constantroots = constantroots self.roots = [] self.pseudo_root_pointers = NULL self.llinterp = llinterp + self.types = types + self._is_varsize = [] + self._offsets_to_gc_pointers = [] + self._varsize_item_sizes = [] + self._varsize_offset_to_variable_part = [] + self._varsize_offset_to_length = [] + self._varsize_offsets_to_gcpointers_in_var_part = [] + tttid = zip(*zip(*type_to_typeid.items())[::-1]) + tttid.sort() + tttid = zip(*zip(*tttid)[::-1]) + for TYPE, typeid in tttid: + varsize = (isinstance(TYPE, lltype.Array) or + (isinstance(TYPE, lltype.Struct) and + TYPE._arrayfld is not None)) + self._is_varsize.append(varsize) + self._offsets_to_gc_pointers.append( + lltypelayout.offsets_to_gc_pointers(TYPE)) + if varsize: + self._varsize_item_sizes.append( + lltypelayout.get_variable_size(TYPE)) + self._varsize_offset_to_variable_part.append( + lltypelayout.get_fixed_size(TYPE)) + self._varsize_offset_to_length.append( + lltypelayout.varsize_offset_to_length(TYPE)) + self._varsize_offsets_to_gcpointers_in_var_part.append( + lltypelayout.varsize_offsets_to_gcpointers_in_var_part(TYPE)) + else: + self._varsize_item_sizes.append(0) + self._varsize_offset_to_variable_part.append(0) + self._varsize_offset_to_length.append(0) + self._varsize_offsets_to_gcpointers_in_var_part.append([]) def update_changed_addresses(self): for i, root in enumerate(self.roots): @@ -20,21 +52,26 @@ root.__dict__['_address'] = self.pseudo_root_pointers.address[i] def get_typeid(self, TYPE): - if TYPE not in self.type_to_typeid: - index = len(self.types) - self.type_to_typeid[TYPE] = index - self.types.append(TYPE) typeid = self.type_to_typeid[TYPE] return typeid - def get_contained_pointers(self, addr, typeid): - TYPE = self.types[typeid] - ptr = lltypesimulation.simulatorptr(lltype.Ptr(TYPE), addr) - ll = AddressLinkedList() - offsets = ptr.get_offsets_of_contained_pointers() - for offset in offsets: - ll.append(addr + offset) - return ll + def is_varsize(self, typeid): + return self._is_varsize[typeid] + + def offsets_to_gc_pointers(self, typeid): + return self._offsets_to_gc_pointers[typeid] + + def varsize_item_sizes(self, typeid): + return self._varsize_item_sizes[typeid] + + def varsize_offset_to_variable_part(self, typeid): + return self._varsize_offset_to_variable_part[typeid] + + def varsize_offset_to_length(self, typeid): + return self._varsize_offset_to_length[typeid] + + def varsize_offsets_to_gcpointers_in_var_part(self, typeid): + return self._varsize_offsets_to_gcpointers_in_var_part[typeid] def get_roots(self): print "getting roots" Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypelayout.py (original) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Fri Aug 19 18:52:17 2005 @@ -86,3 +86,41 @@ return fixedsize else: return fixedsize + i * varsize + + +# _____________________________________________________________________________ +# the following functions are used to find contained pointers + + +def offsets_to_gc_pointers(TYPE): + if isinstance(TYPE, lltype.Struct): + offsets = [] + layout = get_layout(TYPE) + for name in TYPE._names: + FIELD = getattr(TYPE, name) + if (isinstance(FIELD, lltype.Ptr) and FIELD._needsgc() and + FIELD.TO is not lltype.PyObject): + offsets.append(layout[name]) + elif isinstance(FIELD, lltype.Struct): + suboffsets = offsets_to_gc_pointers(FIELD) + offsets += [s + layout[name] for s in suboffsets] + return offsets + return [] + +def varsize_offset_to_length(TYPE): + if isinstance(TYPE, lltype.Array): + return 0 + elif isinstance(TYPE, lltype.Struct): + layout = get_layout(TYPE) + return layout[TYPE._arrayfld] + +def varsize_offsets_to_gcpointers_in_var_part(TYPE): + if isinstance(TYPE, lltype.Array): + if isinstance(TYPE.OF, lltype.Ptr): + return [0] + elif isinstance(TYPE.OF, lltype.Struct): + return offsets_to_gc_pointers(TYPE.OF) + return [] + elif isinstance(TYPE, lltype.Struct): + return offsets_to_gc_pointers(getattr(TYPE, TYPE._arrayfld)) + Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Fri Aug 19 18:52:17 2005 @@ -164,38 +164,6 @@ def __repr__(self): return '' % (self._TYPE.TO, self._address) - def get_offsets_of_contained_pointers(self): - if isinstance(self._TYPE.TO, lltype.Struct): - offsets = self._get_offsets_of_contained_pointers_struct() - elif isinstance(self._TYPE.TO, lltype.Array): - offsets = self._get_offsets_of_contained_pointers_array() - return offsets - - def _get_offsets_of_contained_pointers_struct(self): - offsets = [] - for name in self._TYPE.TO._names: - FIELD = getattr(self._TYPE.TO, name) - if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc(): - offsets.append(self._layout[name]) - elif isinstance(FIELD, (lltype.Struct, lltype.Array)): - embedded_ptr = getattr(self, name) - suboffsets = embedded_ptr.get_offsets_of_contained_pointers() - offsets += [s + self._layout[name] for s in suboffsets] - return offsets - - def _get_offsets_of_contained_pointers_array(self): - offsets = [] - if (isinstance(self._TYPE.TO.OF, lltype.Ptr) and - self._TYPE.TO.OF._needsgc()): - for i in range(len(self)): - offsets.append(self._layout[0] + i * self._layout[1]) - elif isinstance(self._TYPE.TO.OF, lltype.GcStruct): - for i in range(len(self)): - suboffsets += self[i].get_offsets_of_contained_pointers() - offsets += [s + self._layout[0] + i * self._layout[1] - for s in suboffsets] - return offsets - def cast_pointer(PTRTYPE, ptr): if not isinstance(ptr, simulatorptr) or not isinstance(PTRTYPE, lltype.Ptr): Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 19 18:52:17 2005 @@ -36,14 +36,12 @@ ll.append(root) return ll - def get_contained_pointers(self, addr, typeid): - if addr is NULL: - return AddressLinkedList() + def is_varsize(self, typeid): + False + + def offsets_to_gc_pointers(self, typeid): layout = self.layout_mapping[typeid] - result = AddressLinkedList() - for offset in layout: - result.append(addr + offset) - return result + return layout class TestMarkSweepGC(object): def test_simple(self): From arigo at codespeak.net Fri Aug 19 18:59:54 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Aug 2005 18:59:54 +0200 (CEST) Subject: [pypy-svn] r16170 - in pypy/dist/pypy: objspace/std objspace/std/test rpython rpython/test Message-ID: <20050819165954.E66C427B6C@code1.codespeak.net> Author: arigo Date: Fri Aug 19 18:59:48 2005 New Revision: 16170 Modified: pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/test/test_stringobject.py pypy/dist/pypy/rpython/rarithmetic.py pypy/dist/pypy/rpython/rstr.py pypy/dist/pypy/rpython/test/test_rstr.py Log: Using the implementation provided by rpython for str.find(), str.rfind() and hash(str). * rarithmetic._hash_string() computes the hash of a string; this is used from stringobject.py instead of directly hash(s), beause otherwise we would get different hash values in some cases (0/-1 special cases). This would be a problem for strings that are used as dictionary keys when the dictionary is frozen by translation. * rtyper support for the full str.find(substr, start=0, end=None) as well as str.rfind. This allows us to clean up stringobject.py quite a bit, and probably gives an important speed-up. * fix in ll_find() for the case of an empty substring; wrote direct tests for ll_find() and ll_rfind(). * eventually removed the W_StringObject.w_hash cache, as rpython provides its own hash caching. (Right now this cache doesn't work with PyPy over CPython -- don't know if it causes a performance problem) * fix bug in str.count() (see added test) Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Fri Aug 19 18:59:48 2005 @@ -2,7 +2,8 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from pypy.rpython.rarithmetic import intmask, ovfcheck +from pypy.rpython.rarithmetic import intmask, ovfcheck, _hash_string +from pypy.rpython.objectmodel import we_are_translated from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.sliceobject import W_SliceObject from pypy.objspace.std import slicetype @@ -20,7 +21,6 @@ def __init__(w_self, space, str): W_Object.__init__(w_self, space) w_self._value = str - w_self.w_hash = None def __repr__(w_self): """ representation for debugging purposes """ @@ -275,9 +275,7 @@ splitcount = maxsplit while splitcount: - next = _find(value, by, start, len(value), 1) - #next = value.find(by, start) #of course we cannot use - #the find method, + next = value.find(by, start) if next < 0: break res_w.append(W_StringObject(space, value[start:next])) @@ -339,9 +337,7 @@ splitcount = maxsplit while splitcount: - next = _find(value, by, 0, end, -1) - #next = value.rfind(by, end) #of course we cannot use - #the find method, + next = value.rfind(by, 0, end) if next < 0: break res_w.append(W_StringObject(space, value[next+bylen:end])) @@ -445,32 +441,33 @@ start = space.int_w(w_start) end = space.int_w(w_end) + assert start >= 0 + assert end >= 0 return (self, sub, start, end) def contains__String_String(space, w_self, w_sub): self = w_self._value sub = w_sub._value - return space.newbool(_find(self, sub, 0, len(self), 1) >= 0) + return space.newbool(self.find(sub) >= 0) def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = _find(self, sub, start, end, 1) + res = self.find(sub, start, end) return space.wrap(res) def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = _find(self, sub, start, end, -1) + res = self.rfind(sub, start, end) return space.wrap(res) def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = _find(self, sub, start, end, 1) - - if res == -1: + res = self.find(sub, start, end) + if res < 0: raise OperationError(space.w_ValueError, space.wrap("substring not found in string.index")) @@ -480,8 +477,8 @@ def str_rindex__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end): (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end) - res = _find(self, sub, start, end, -1) - if res == -1: + res = self.rfind(sub, start, end) + if res < 0: raise OperationError(space.w_ValueError, space.wrap("substring not found in string.rindex")) @@ -499,19 +496,17 @@ #what do we have to replace? startidx = 0 - endidx = len(input) indices = [] - foundidx = _find(input, sub, startidx, endidx, 1) - while foundidx > -1 and (maxsplit == -1 or maxsplit > 0): + foundidx = input.find(sub, startidx) + while foundidx >= 0 and maxsplit != 0: indices.append(foundidx) if len(sub) == 0: #so that we go forward, even if sub is empty startidx = foundidx + 1 else: startidx = foundidx + len(sub) - foundidx = _find(input, sub, startidx, endidx, 1) - if maxsplit != -1: - maxsplit = maxsplit - 1 + foundidx = input.find(sub, startidx) + maxsplit = maxsplit - 1 indiceslen = len(indices) buf = [' '] * (len(input) - indiceslen * len(sub) + indiceslen * len(by)) startidx = 0 @@ -534,52 +529,52 @@ bufpos = bufpos + 1 return space.wrap("".join(buf)) -def _find(self, sub, start, end, dir): - - length = len(self) +##def _find(self, sub, start, end, dir): - #adjust_indicies - if (end > length): - end = length - elif (end < 0): - end += length - if (end < 0): - end = 0 - if (start < 0): - start += length - if (start < 0): - start = 0 +## length = len(self) - if dir > 0: - if len(sub) == 0 and start < end: - return start - - end = end - len(sub) + 1 - - for i in range(start, end): - match = 1 - for idx in range(len(sub)): - if sub[idx] != self[idx+i]: - match = 0 - break - if match: - return i - return -1 - else: - if len(sub) == 0 and start < end: - return end +## #adjust_indicies +## if (end > length): +## end = length +## elif (end < 0): +## end += length +## if (end < 0): +## end = 0 +## if (start < 0): +## start += length +## if (start < 0): +## start = 0 + +## if dir > 0: +## if len(sub) == 0 and start < end: +## return start + +## end = end - len(sub) + 1 + +## for i in range(start, end): +## match = 1 +## for idx in range(len(sub)): +## if sub[idx] != self[idx+i]: +## match = 0 +## break +## if match: +## return i +## return -1 +## else: +## if len(sub) == 0 and start < end: +## return end - end = end - len(sub) +## end = end - len(sub) - for j in range(end, start-1, -1): - match = 1 - for idx in range(len(sub)): - if sub[idx] != self[idx+j]: - match = 0 - break - if match: - return j - return -1 +## for j in range(end, start-1, -1): +## match = 1 +## for idx in range(len(sub)): +## if sub[idx] != self[idx+j]: +## match = 0 +## break +## if match: +## return j +## return -1 def _strip(space, w_self, w_chars, left, right): @@ -668,15 +663,19 @@ w_end = slicetype.adapt_bound(space, w_end, space.wrap(len(u_self))) u_start = space.int_w(w_start) u_end = space.int_w(w_end) - - count = 0 + assert u_start >= 0 + assert u_end >= 0 - pos = u_start - 1 - while 1: - pos = _find(u_self, u_arg, pos+1, u_end, 1) - if pos == -1: - break - count += 1 + if len(u_arg) == 0: + count = len(u_self) + 1 + else: + count = 0 + while 1: + pos = u_self.find(u_arg, u_start, u_end) + if pos < 0: + break + count += 1 + u_start = pos + len(u_arg) return W_IntObject(space, count) @@ -804,21 +803,14 @@ return w_str._value def hash__String(space, w_str): - w_hash = w_str.w_hash - if w_hash is None: - s = w_str._value - try: - x = ord(s[0]) << 7 - except IndexError: - x = 0 - else: - for c in s: - x = (1000003*x) ^ ord(c) - x ^= len(s) - # unlike CPython, there is no reason to avoid to return -1 - w_hash = W_IntObject(space, intmask(x)) - w_str.w_hash = w_hash - return w_hash + s = w_str._value + if we_are_translated(): + x = hash(s) # to use the hash cache in rpython strings + else: + x = _hash_string(s) # to make sure we get the same hash as rpython + # (otherwise translation will freeze W_DictObjects where we can't find + # the keys any more!) + return W_IntObject(space, x) ##EQ = 1 Modified: pypy/dist/pypy/objspace/std/test/test_stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_stringobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_stringobject.py Fri Aug 19 18:59:48 2005 @@ -313,6 +313,7 @@ assert 'aaa'.count('a', -10) == 3 assert 'aaa'.count('a', 0, -1) == 2 assert 'aaa'.count('a', 0, -10) == 0 + assert 'ababa'.count('aba') == 1 def test_startswith(self): assert 'ab'.startswith('ab') is True @@ -592,7 +593,7 @@ def test_hash(self): # check that we have the same hash as CPython for at least 31 bits # (but don't go checking CPython's special case -1) - assert hash('') == 0 + # disabled: assert hash('') == 0 --- different special case assert hash('hello') & 0x7fffffff == 0x347697fd assert hash('hello world!') & 0x7fffffff == 0x2f0bb411 Modified: pypy/dist/pypy/rpython/rarithmetic.py ============================================================================== --- pypy/dist/pypy/rpython/rarithmetic.py (original) +++ pypy/dist/pypy/rpython/rarithmetic.py Fri Aug 19 18:59:48 2005 @@ -383,3 +383,20 @@ def formatd(fmt, x): return fmt % (x,) + +# a common string hash function + +def _hash_string(s): + length = len(s) + if length == 0: + x = -1 + else: + x = ord(s[0]) << 7 + i = 0 + while i < length: + x = (1000003*x) ^ ord(s[i]) + i += 1 + x ^= length + if x == 0: + x = -1 + return intmask(x) Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Fri Aug 19 18:59:48 2005 @@ -3,7 +3,7 @@ from pypy.annotation import model as annmodel from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr from pypy.rpython.rmodel import StringRepr, CharRepr, inputconst, UniCharRepr -from pypy.rpython.rarithmetic import intmask +from pypy.rpython.rarithmetic import intmask, _hash_string from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rtuple import TupleRepr from pypy.rpython import rint @@ -107,9 +107,29 @@ v_str, v_value = hop.inputargs(string_repr, string_repr) return hop.gendirectcall(ll_endswith, v_str, v_value) - def rtype_method_find(_, hop): - v_str, v_value = hop.inputargs(string_repr, string_repr) - return hop.gendirectcall(ll_find, v_str, v_value) + def rtype_method_find(_, hop, reverse=False): + v_str = hop.inputarg(string_repr, arg=0) + v_value = hop.inputarg(string_repr, arg=1) + if hop.nb_args > 2: + v_start = hop.inputarg(Signed, arg=2) + if not hop.args_s[2].nonneg: + raise TyperError("str.find() start must be proven non-negative") + else: + v_start = hop.inputconst(Signed, 0) + if hop.nb_args > 3: + v_end = hop.inputarg(Signed, arg=3) + if not hop.args_s[2].nonneg: + raise TyperError("str.find() end must be proven non-negative") + else: + v_end = hop.gendirectcall(ll_strlen, v_str) + if reverse: + llfn = ll_rfind + else: + llfn = ll_find + return hop.gendirectcall(llfn, v_str, v_value, v_start, v_end) + + def rtype_method_rfind(self, hop): + return self.rtype_method_find(hop, reverse=True) def rtype_method_upper(_, hop): v_str, = hop.inputargs(string_repr) @@ -541,19 +561,8 @@ # special non-computed-yet value. x = s.hash if x == 0: - length = len(s.chars) - if length == 0: - x = -1 - else: - x = ord(s.chars[0]) << 7 - i = 0 - while i < length: - x = (1000003*x) ^ ord(s.chars[i]) - i += 1 - x ^= length - if x == 0: - x = -1 - s.hash = intmask(x) + x = _hash_string(s.chars) + s.hash = x return x def ll_strconcat(s1, s2): @@ -643,18 +652,20 @@ return True -def ll_find(s1, s2): +def ll_find(s1, s2, start, end): """Knuth Morris Prath algorithm for substring match""" - len1 = len(s1.chars) len2 = len(s2.chars) + if len2 == 0: + return start # Construct the array of possible restarting positions # T = Array_of_ints [-1..len2] # T[-1] = -1 s2.chars[-1] is supposed to be unequal to everything else T = malloc( SIGNED_ARRAY, len2 ) - i = 0 - j = -1 + T[0] = 0 + i = 1 + j = 0 while i=0 and s2.chars[i] == s2.chars[j]: + if s2.chars[i] == s2.chars[j]: j += 1 T[i] = j i += 1 @@ -667,8 +678,8 @@ # Now the find algorithm i = 0 - m = 0 - while m+i0: + m = m + i - e i = e return -1 - + +def ll_rfind(s1, s2, start, end): + """Reversed version of ll_find()""" + len2 = len(s2.chars) + if len2 == 0: + return end + # Construct the array of possible restarting positions + T = malloc( SIGNED_ARRAY, len2 ) + T[0] = 1 + i = 1 + j = 1 + while i1: + j = T[j-2] + else: + T[i] = 1 + i += 1 + j = 1 + + # Now the find algorithm + i = 1 + m = end + while m-i>=start: + if s1.chars[m-i]==s2.chars[len2-i]: + if i==len2: + return m-i + i += 1 + else: + # mismatch, go back to the last possible starting pos + if i==1: + m -= 1 + else: + e = T[i-2] + m = m - i + e + i = e + return -1 + emptystr = string_repr.convert_const("") def ll_upper(s): Modified: pypy/dist/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rstr.py (original) +++ pypy/dist/pypy/rpython/test/test_rstr.py Fri Aug 19 18:59:48 2005 @@ -1,10 +1,28 @@ +import random from pypy.translator.translator import Translator from pypy.rpython.lltype import * -from pypy.rpython.rstr import parse_fmt_string +from pypy.rpython.rstr import parse_fmt_string, ll_find, ll_rfind, STR from pypy.rpython.rtyper import RPythonTyper, TyperError from pypy.rpython.test.test_llinterp import interpret, interpret_raises from pypy.rpython.llinterp import LLException +def llstr(s): + p = malloc(STR, len(s)) + for i in range(len(s)): + p.chars[i] = s[i] + return p + +def test_ll_find_rfind(): + for i in range(50): + n1 = random.randint(0, 10) + s1 = ''.join([random.choice("ab") for i in range(n1)]) + n2 = random.randint(0, 5) + s2 = ''.join([random.choice("ab") for i in range(n2)]) + res = ll_find(llstr(s1), llstr(s2), 0, n1) + assert res == s1.find(s2) + res = ll_rfind(llstr(s1), llstr(s2), 0, n1) + assert res == s1.rfind(s2) + def test_simple(): def fn(i): s = 'hello' @@ -200,13 +218,36 @@ def test_find(): def fn(i, j): s1 = ['one two three', 'abc abcdab abcdabcdabde'] - s2 = ['one', 'two', 'abcdab', 'one tou', 'abcdefgh', 'fortytwo'] + s2 = ['one', 'two', 'abcdab', 'one tou', 'abcdefgh', 'fortytwo', ''] return s1[i].find(s2[j]) for i in range(2): - for j in range(6): + for j in range(7): res = interpret(fn, [i,j]) assert res == fn(i, j) +def test_find_with_start(): + def fn(i): + assert i >= 0 + return 'ababcabc'.find('abc', i) + for i in range(9): + res = interpret(fn, [i]) + assert res == fn(i) + +def test_find_with_start_end(): + def fn(i, j): + assert i >= 0 + assert j >= 0 + return 'ababcabc'.find('abc', i, j) + for (i, j) in [(1,7), (2,6), (3,7), (3,8)]: + res = interpret(fn, [i, j]) + assert res == fn(i, j) + +def test_rfind(): + def fn(): + return 'aaa'.rfind('a') + 'aaa'.rfind('a', 1) + 'aaa'.rfind('a', 1, 2) + res = interpret(fn, []) + assert res == 2 + 2 + 1 + def test_upper(): def fn(i): strings = ['', ' ', 'upper', 'UpPeR', ',uppEr,'] From cfbolz at codespeak.net Fri Aug 19 19:07:31 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 19:07:31 +0200 (CEST) Subject: [pypy-svn] r16171 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050819170731.891A227B64@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 19:07:30 2005 New Revision: 16171 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: made the gc's malloc calculate the size of the malloced object itself. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Fri Aug 19 19:07:30 2005 @@ -21,9 +21,12 @@ self.malloced_objects = AddressLinkedList() self.objectmodel = objectmodel - def malloc(self, typeid, size): + def malloc(self, typeid, length=0): if self.bytes_malloced > self.collect_every_bytes: self.collect() + size = self.objectmodel.fixed_size(typeid) + if self.objectmodel.is_varsize(typeid): + size += length * self.objectmodel.varsize_item_sizes(typeid) size_gc_header = self.size_gc_header() result = raw_malloc(size + size_gc_header) print "mallocing %s, size %s at %s" % (typeid, size, result) Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Fri Aug 19 19:07:30 2005 @@ -16,6 +16,7 @@ self.types = types self._is_varsize = [] self._offsets_to_gc_pointers = [] + self._fixed_size = [] self._varsize_item_sizes = [] self._varsize_offset_to_variable_part = [] self._varsize_offset_to_length = [] @@ -30,6 +31,8 @@ self._is_varsize.append(varsize) self._offsets_to_gc_pointers.append( lltypelayout.offsets_to_gc_pointers(TYPE)) + self._fixed_size.append( + lltypelayout.get_fixed_size(TYPE)) if varsize: self._varsize_item_sizes.append( lltypelayout.get_variable_size(TYPE)) @@ -61,6 +64,9 @@ def offsets_to_gc_pointers(self, typeid): return self._offsets_to_gc_pointers[typeid] + def fixed_size(self, typeid): + return self._fixed_size[typeid] + def varsize_item_sizes(self, typeid): return self._varsize_item_sizes[typeid] @@ -99,8 +105,7 @@ def malloc(self, TYPE, size=0): typeid = self.objectmodel.get_typeid(TYPE) - address = self.gc.malloc(typeid, - lltypesimulation.sizeof(TYPE, size)) + address = self.gc.malloc(typeid, size) return lltypesimulation.init_object_on_address(address, TYPE, size) self.objectmodel.update_changed_addresses() return result Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Fri Aug 19 19:07:30 2005 @@ -25,9 +25,10 @@ """Object model for testing purposes: you can specify roots and a layout_mapping which is a dictionary of typeids to a list of offsets of pointers in an object""" - def __init__(self, roots, layout_mapping): + def __init__(self, roots, layout_mapping, size_mapping): self.roots = roots self.layout_mapping = layout_mapping + self.size_mapping = size_mapping def get_roots(self): self.roots @@ -39,9 +40,11 @@ def is_varsize(self, typeid): False + def fixed_size(self, typeid): + return self.size_mapping[typeid] + def offsets_to_gc_pointers(self, typeid): - layout = self.layout_mapping[typeid] - return layout + return self.layout_mapping[typeid] class TestMarkSweepGC(object): def test_simple(self): @@ -49,27 +52,27 @@ roots = [variables + i * INT_SIZE for i in range(4)] layout0 = [] #int layout1 = [0, INT_SIZE] #(ptr, ptr) - om = PseudoObjectModel(roots, {0: layout0, 1: layout1}) + om = PseudoObjectModel(roots, {0: layout0, 1: layout1}, {0: INT_SIZE, 1: 2 * INT_SIZE}) gc = MarkSweepGC(om, 2 ** 16) - variables.address[0] = gc.malloc(0, INT_SIZE) - variables.address[1] = gc.malloc(0, INT_SIZE) - variables.address[2] = gc.malloc(0, INT_SIZE) - variables.address[3] = gc.malloc(0, INT_SIZE) + variables.address[0] = gc.malloc(0) + variables.address[1] = gc.malloc(0) + variables.address[2] = gc.malloc(0) + variables.address[3] = gc.malloc(0) print "roots", roots gc.collect() #does not crash - addr = gc.malloc(0, INT_SIZE) + addr = gc.malloc(0) addr.signed[0] = 1 print "roots", roots gc.collect() py.test.raises(MemorySimulatorError, "addr.signed[0]") - variables.address[0] = gc.malloc(1, 2 * INT_SIZE) + variables.address[0] = gc.malloc(1) variables.address[0].address[0] = variables.address[1] variables.address[0].address[1] = NULL print "roots", roots gc.collect() #does not crash - addr0 = gc.malloc(1, 2 * INT_SIZE) + addr0 = gc.malloc(1) addr0.address[1] = NULL - addr1 = gc.malloc(1, 2 * INT_SIZE) + addr1 = gc.malloc(1) addr1.address[0] = addr1.address[1] = NULL addr0.address[0] = addr1 addr2 = variables.address[1] From arigo at codespeak.net Fri Aug 19 19:09:04 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Aug 2005 19:09:04 +0200 (CEST) Subject: [pypy-svn] r16172 - in pypy/dist/pypy: annotation rpython rpython/module Message-ID: <20050819170904.C56E127B64@code1.codespeak.net> Author: arigo Date: Fri Aug 19 19:08:54 2005 New Revision: 16172 Added: pypy/dist/pypy/rpython/rexternalobj.py (contents, props changed) Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/annotation/model.py pypy/dist/pypy/annotation/unaryop.py pypy/dist/pypy/rpython/annlowlevel.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/support.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rmodel.py pypy/dist/pypy/rpython/rspecialcase.py pypy/dist/pypy/rpython/rtyper.py Log: Support for "external types" for annotation and rtyping, following the same lines as external functions. Some types like thread.LockType can be declared in the new "typetable" of rpython.extfunctable. These types must have a simple interface -- basically, only methods, which are themselves external functions. The annotator uses a new SomeExternalObject to track objects of one of these external types. The rtyper turns them into pointers to opaque data. There is some changes all over the place to support this kind of usage of opaque data; I'm not sure yet if it's really nice to use opaque types for this, because I'm unsure how to support the result in genc. (The problem is that this gives pointers to opaque objects that still need the same memory management as pointers to regular structs...) Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Fri Aug 19 19:08:54 2005 @@ -5,7 +5,7 @@ from __future__ import generators import sys from types import FunctionType, ClassType, MethodType -from types import BuiltinMethodType +from types import BuiltinMethodType, NoneType from pypy.tool.ansi_print import ansi_print from pypy.annotation.model import * from pypy.annotation.classdef import ClassDef, isclassdef @@ -168,9 +168,7 @@ def __setstate__(self, dic): self.__dict__.update(dic) # normal action - # import ordering hack - global BUILTIN_ANALYZERS - from pypy.annotation.builtin import BUILTIN_ANALYZERS + delayed_imports() def __init__(self, annotator): self.annotator = annotator @@ -201,9 +199,7 @@ self.stats = Stats(self) - # import ordering hack - global BUILTIN_ANALYZERS - from pypy.annotation.builtin import BUILTIN_ANALYZERS + delayed_imports() def count(self, category, *args): self.stats.count(category, *args) @@ -337,6 +333,8 @@ result.dictdef.generalize_value(self.immutablevalue(ev)) elif ishashable(x) and x in BUILTIN_ANALYZERS: result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (x.__module__, x.__name__)) + elif tp in EXTERNAL_TYPE_ANALYZERS: + result = SomeExternalObject(tp) elif isinstance(x, lltype._ptr): result = SomePtr(lltype.typeOf(x)) elif isinstance(x, lladdress.address): @@ -349,9 +347,8 @@ x.im_self._freeze_() if hasattr(x, '__self__') and x.__self__ is not None: s_self = self.immutablevalue(x.__self__) - try: - result = s_self.find_method(x.__name__) - except AttributeError: + result = s_self.find_method(x.__name__) + if result is None: result = SomeObject() else: return self.getpbc(x) @@ -418,6 +415,10 @@ elif t is dict: return SomeDict(MOST_GENERAL_DICTDEF) # can't do tuple + elif t is NoneType: + return self.getpbc(None) + elif t in EXTERNAL_TYPE_ANALYZERS: + return SomeExternalObject(t) elif t.__module__ != '__builtin__' and t not in self.pbctypes: classdef = self.getclassdef(t) return SomeInstance(classdef) @@ -712,3 +713,10 @@ return TLS.bookkeeper except AttributeError: return None + + +def delayed_imports(): + # import ordering hack + global BUILTIN_ANALYZERS, EXTERNAL_TYPE_ANALYZERS + from pypy.annotation.builtin import BUILTIN_ANALYZERS + from pypy.annotation.builtin import EXTERNAL_TYPE_ANALYZERS Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Fri Aug 19 19:08:54 2005 @@ -262,6 +262,7 @@ # collect all functions import __builtin__ BUILTIN_ANALYZERS = {} +EXTERNAL_TYPE_ANALYZERS = {} for name, value in globals().items(): if name.startswith('builtin_'): original = getattr(__builtin__, name[8:]) @@ -366,8 +367,19 @@ from pypy.rpython import extfunctable -# import annotation information for external functions -# from the extfunctable.table into our own annotation specific table -for func, extfuncinfo in extfunctable.table.iteritems(): - BUILTIN_ANALYZERS[func] = extfuncinfo.annotation +def update_exttables(): + # import annotation information for external functions + # from the extfunctable.table into our own annotation specific table + for func, extfuncinfo in extfunctable.table.iteritems(): + BUILTIN_ANALYZERS[func] = extfuncinfo.annotation + + # import annotation information for external types + # from the extfunctable.typetable into our own annotation specific table + for typ, exttypeinfo in extfunctable.typetable.iteritems(): + EXTERNAL_TYPE_ANALYZERS[typ] = exttypeinfo.get_annotations() + +# Note: calls to declare() may occur after builtin.py is first imported. +# We must track future changes to the extfunctables. +extfunctable.table_callbacks.append(update_exttables) +update_exttables() Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Fri Aug 19 19:08:54 2005 @@ -380,6 +380,19 @@ def can_be_none(self): return False + +class SomeExternalObject(SomeObject): + """Stands for an object of 'external' type. External types are defined + in pypy.rpython.extfunctable.declaretype(), and represent simple types + with some methods that need direct back-end support.""" + + def __init__(self, knowntype): + self.knowntype = knowntype + + def can_be_none(self): + return True + + class SomeImpossibleValue(SomeObject): """The empty set. Instances are placeholders for objects that will never show up at run-time, e.g. elements of an empty list.""" Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Fri Aug 19 19:08:54 2005 @@ -11,6 +11,7 @@ from pypy.annotation.model import SomeTuple, SomeImpossibleValue from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeFloat from pypy.annotation.model import SomeIterator, SomePBC, new_or_old_class +from pypy.annotation.model import SomeExternalObject from pypy.annotation.model import SomeTypedAddressAccess, SomeAddress from pypy.annotation.model import unionof, set, setunion, missing_operation from pypy.annotation.bookkeeper import getbookkeeper, RPythonCallsSpace @@ -119,18 +120,21 @@ def find_method(obj, name): "Look for a special-case implementation for the named method." - analyser = getattr(obj.__class__, 'method_' + name) - return SomeBuiltin(analyser, obj, name) + try: + analyser = getattr(obj.__class__, 'method_' + name) + except AttributeError: + return None + else: + return SomeBuiltin(analyser, obj, name) def getattr(obj, s_attr): # get a SomeBuiltin if the SomeObject has # a corresponding method to handle it if s_attr.is_constant() and isinstance(s_attr.const, str): attr = s_attr.const - try: - return obj.find_method(attr) - except AttributeError: - pass + s_method = obj.find_method(attr) + if s_method is not None: + return s_method # if the SomeObject is itself a constant, allow reading its attrs if obj.is_constant() and hasattr(obj.const, attr): return immutablevalue(getattr(obj.const, attr)) @@ -306,7 +310,10 @@ def method_endswith(str, frag): return SomeBool() - def method_find(str, frag): + def method_find(str, frag, start=None, end=None): + return SomeInteger() + + def method_rfind(str, frag, start=None, end=None): return SomeInteger() def method_join(str, s_list): @@ -480,6 +487,16 @@ return immutablevalue(outcome) +class __extend__(SomeExternalObject): + def find_method(obj, name): + "Look for a special-case implementation for the named method." + type_analyser = builtin.EXTERNAL_TYPE_ANALYZERS[obj.knowntype] + if name in type_analyser: + analyser = type_analyser[name] + return SomeBuiltin(analyser, obj, name) + return SomeObject.find_method(obj, name) + + # annotation of low-level types from pypy.annotation.model import SomePtr, ll_to_annotation, annotation_to_lltype class __extend__(SomePtr): Modified: pypy/dist/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/dist/pypy/rpython/annlowlevel.py (original) +++ pypy/dist/pypy/rpython/annlowlevel.py Fri Aug 19 19:08:54 2005 @@ -5,7 +5,9 @@ import types from pypy.annotation import model as annmodel from pypy.annotation.specialize import decide_callable -from pypy.annotation.policy import BasicAnnotatorPolicy +from pypy.annotation.policy import AnnotatorPolicy +from pypy.rpython import lltype +from pypy.rpython import extfunctable def not_const(s_obj): # xxx move it somewhere else if s_obj.is_constant(): @@ -29,10 +31,10 @@ def __str__(self): return getattr(self.val, '__name__', repr(self.val)) + 'Const' -class LowLevelAnnotatorPolicy(BasicAnnotatorPolicy): +class LowLevelAnnotatorPolicy(AnnotatorPolicy): allow_someobjects = False - def specialize(pol, bookkeeper, spaceop, func, args, mono): + def default_specialize(pol, bookkeeper, ignored, spaceop, func, args, mono): args_s, kwds_s = args.unpack() assert not kwds_s if not args_s or not isinstance(func, types.FunctionType): @@ -53,7 +55,20 @@ # for module/ll_* key.append(s_obj.__class__) return tuple(key), bookkeeper.build_args('simple_call', new_args_s) - + + def override__to_rexternalobj(pol, s_obj): + assert isinstance(s_obj, annmodel.SomeExternalObject) + exttypeinfo = extfunctable.typetable[s_obj.knowntype] + OPAQUE = exttypeinfo.get_opaque_lltype() + return annmodel.SomePtr(lltype.Ptr(OPAQUE)) + + def override__from_rexternalobj(pol, s_objptr): + assert isinstance(s_objptr, annmodel.SomePtr) + OPAQUE = s_objptr.ll_ptrtype.TO + assert isinstance(OPAQUE, lltype.OpaqueType) + exttypeinfo = OPAQUE.exttypeinfo + return annmodel.SomeExternalObject(exttypeinfo.typ) + def annotate_lowlevel_helper(annotator, ll_function, args_s): saved = annotator.policy Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Fri Aug 19 19:08:54 2005 @@ -11,9 +11,12 @@ def __init__(self, func, annotation, ll_function_path, ll_annotable, backend_functiontemplate): self.func = func self.annotation = annotation - modulename, ignored = ll_function_path.split('/') - self.ll_module = ImportMe('pypy.rpython.module.%s' % modulename) - self.ll_function_name = ll_function_path.replace('/', '_') + modulename, tail = ll_function_path.split('/') + if '.' not in modulename: + modulename = 'pypy.rpython.module.%s' % modulename + self.ll_module = ImportMe(modulename) + lastmodulename = modulename[modulename.rfind('.')+1:] + self.ll_function_name = '%s_%s' % (lastmodulename, tail) self.ll_annotable = ll_annotable self.backend_functiontemplate = backend_functiontemplate @@ -24,6 +27,34 @@ ll_function = property(get_ll_function) +class ExtTypeInfo: + def __init__(self, typ, tag, methods): + self.typ = typ + self.tag = tag + self.TYPE = None + self.methods = methods # {'name': ExtFuncInfo()} + + def get_annotation(self, methodname): + return self.methods[methodname].annotation + + def get_annotations(self): + return dict([(name, self.get_annotation(name)) + for name in self.methods]) + + def get_func_infos(self): + for extfuncinfo in self.methods.itervalues(): + if extfuncinfo.func is not None: + yield (extfuncinfo.func, extfuncinfo) + + def get_opaque_lltype(self): + if self.TYPE is None: + from pypy.rpython import lltype + OPAQUE = lltype.OpaqueType(self.tag) + OPAQUE.exttypeinfo = self + self.TYPE = OPAQUE + return self.TYPE + + class ImportMe: "Lazily imported module, for circular imports :-/" def __init__(self, modulename): @@ -35,6 +66,8 @@ return self._mod +table_callbacks = [] # to track declare() that occur after 'table' is read + table = {} def declare(func, annotation, ll_function, ll_annotable=True, backend_functiontemplate=None): # annotation can be a function computing the annotation @@ -45,7 +78,31 @@ def annotation(*args_s): from pypy.annotation import bookkeeper return bookkeeper.getbookkeeper().valueoftype(typ) - table[func] = ExtFuncInfo(func, annotation, ll_function, ll_annotable, backend_functiontemplate) + info = ExtFuncInfo(func, annotation, ll_function, ll_annotable, backend_functiontemplate) + if func is not None: + table[func] = info + for callback in table_callbacks: + callback() + return info + +typetable = {} +def declaretype(typ, tag, **methodsdecl): + assert isinstance(typ, type) + methods = {} + for name, args in methodsdecl.items(): + # try to get the method object from the typ + for cls in typ.__mro__: + if name in typ.__dict__: + func = typ.__dict__[name] + break + else: + func = None # failed (typical for old-style C types), ignore it + methods[name] = declare(func, *args) + info = ExtTypeInfo(typ, tag, methods) + typetable[typ] = info + for callback in table_callbacks: + callback() + return info # _____________________________________________________________ Modified: pypy/dist/pypy/rpython/module/support.py ============================================================================== --- pypy/dist/pypy/rpython/module/support.py (original) +++ pypy/dist/pypy/rpython/module/support.py Fri Aug 19 19:08:54 2005 @@ -1,3 +1,5 @@ +from pypy.rpython import lltype +from pypy.rpython import extfunctable from pypy.rpython.rstr import STR from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc @@ -17,3 +19,13 @@ while i < n: dstchars[i] = srcchars[i] i += 1 + +def to_rexternalobj(obj): + exttypeinfo = extfunctable.typetable[type(obj)] + OPAQUE = exttypeinfo.get_opaque_lltype() + return lltype.opaqueptr(OPAQUE, name=None, externalobj=obj) +to_rexternalobj._annspecialcase_ = "override:to_rexternalobj" + +def from_rexternalobj(objptr): + return objptr._obj.externalobj +from_rexternalobj._annspecialcase_ = "override:from_rexternalobj" Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Fri Aug 19 19:08:54 2005 @@ -288,8 +288,10 @@ return hop.llops.genexternalcall(ll_function.__name__, vars, resulttype=resulttype, _callable = ll_function) - return sourcetools.func_with_new_name(rtype_extfunc, - "rtype_extfunc_%s" % extfuncinfo.func.__name__) + if extfuncinfo.func is not None: + rtype_extfunc = sourcetools.func_with_new_name(rtype_extfunc, + "rtype_extfunc_%s" % extfuncinfo.func.__name__) + return rtype_extfunc # import rtyping information for external functions # from the extfunctable.table into our own specific table Added: pypy/dist/pypy/rpython/rexternalobj.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/rexternalobj.py Fri Aug 19 19:08:54 2005 @@ -0,0 +1,29 @@ +from pypy.annotation.pairtype import pairtype +from pypy.annotation import model as annmodel +from pypy.rpython import lltype +from pypy.rpython.rmodel import Repr +from pypy.rpython.extfunctable import typetable +from pypy.rpython import rbuiltin +from pypy.tool import sourcetools + + +class __extend__(annmodel.SomeExternalObject): + def rtyper_makerepr(self, rtyper): + return ExternalObjRepr(self.knowntype) + def rtyper_makekey(self): + return self.__class__, self.knowntype + + +class ExternalObjRepr(Repr): + + def __init__(self, knowntype): + self.exttypeinfo = typetable[knowntype] + OPAQUE = self.exttypeinfo.get_opaque_lltype() + self.lowleveltype = lltype.Ptr(OPAQUE) + # The set of methods supported depends on 'knowntype', so we + # cannot have rtype_method_xxx() methods directly on the + # ExternalObjRepr class. But we can store them in 'self' now. + for name, extfuncinfo in self.exttypeinfo.methods.items(): + methodname = 'rtype_method_' + name + bltintyper = rbuiltin.make_rtype_extfunc(extfuncinfo) + setattr(self, methodname, bltintyper) Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Fri Aug 19 19:08:54 2005 @@ -114,9 +114,7 @@ if s_attr.is_constant() and isinstance(s_attr.const, str): attr = s_attr.const s_obj = hop.args_s[0] - try: - s_obj.find_method(attr) # just to check it is here - except AttributeError: + if s_obj.find_method(attr) is None: raise TyperError("no method %s on %r" % (attr, s_obj)) else: # implement methods (of a known name) as just their 'self' Modified: pypy/dist/pypy/rpython/rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/rspecialcase.py (original) +++ pypy/dist/pypy/rpython/rspecialcase.py Fri Aug 19 19:08:54 2005 @@ -27,3 +27,11 @@ def rtype_override_ignore(hop, clsdef): # ignore works for methods too hop.exception_cannot_occur() return inputconst(hop.r_result, None) + +def rtype_identity_function(hop, clsdef): + hop.exception_cannot_occur() + v, = hop.inputargs(hop.args_r[0]) + return v + +rtype_override_to_rexternalobj = rtype_identity_function +rtype_override_from_rexternalobj = rtype_identity_function Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Fri Aug 19 19:08:54 2005 @@ -741,5 +741,6 @@ from pypy.rpython import rslice from pypy.rpython import rlist, rstr, rtuple, rdict from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase +from pypy.rpython import rexternalobj from pypy.rpython import rptr from pypy.rpython import raddress # memory addresses From arigo at codespeak.net Fri Aug 19 19:14:25 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Aug 2005 19:14:25 +0200 (CEST) Subject: [pypy-svn] r16173 - pypy/dist/pypy/interpreter Message-ID: <20050819171425.3915927B64@code1.codespeak.net> Author: arigo Date: Fri Aug 19 19:14:21 2005 New Revision: 16173 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/executioncontext.py pypy/dist/pypy/interpreter/miscutils.py Log: A change in preparation for thread support (which remains completely independent from the core): the 'space.threadlocals' object, which contained the executioncontext, has now a well-defined method-based interface for reading and setting the executioncontext and for "making a pause" between bytecodes, for cooperative scheduling. Thread strategies are implemented by patching 'space.threadlocals' to point to an instance of a different class, with methods that really provide thread support. The default 'space.threadlocals' holds just a single executioncontext, like before. Patching is done in the init method of the selected thread module. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Fri Aug 19 19:14:21 2005 @@ -230,17 +230,17 @@ def getexecutioncontext(self): "Return what we consider to be the active execution context." - ec = self.threadlocals.executioncontext + ec = self.threadlocals.getvalue() if ec is None: ec = self.createexecutioncontext() - self.threadlocals.executioncontext = ec + self.threadlocals.setvalue(ec) return ec def _freeze_(self): # Important: the annotator must not see a prebuilt ExecutionContext # for reasons related to the specialization of the framestack attribute # so we make sure there is no executioncontext at freeze-time - self.threadlocals.executioncontext = None + self.threadlocals.setvalue(None) return True def createexecutioncontext(self): Modified: pypy/dist/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/dist/pypy/interpreter/executioncontext.py (original) +++ pypy/dist/pypy/interpreter/executioncontext.py Fri Aug 19 19:14:21 2005 @@ -20,7 +20,7 @@ self.space.wrap("maximum recursion depth exceeded")) try: frame.f_back = self.framestack.top() - except: + except IndexError: frame.f_back = None if not frame.hide(): @@ -57,6 +57,7 @@ def bytecode_trace(self, frame): "Trace function called before each bytecode." + self.space.threadlocals.yield_thread() if self.is_tracing or frame.w_f_trace is None: return code = getattr(frame, 'pycode') Modified: pypy/dist/pypy/interpreter/miscutils.py ============================================================================== --- pypy/dist/pypy/interpreter/miscutils.py (original) +++ pypy/dist/pypy/interpreter/miscutils.py Fri Aug 19 19:14:21 2005 @@ -82,9 +82,20 @@ class ThreadLocals: - """Thread-local storage.""" - # XXX this is not really thread-local at the moment. - # XXX reconsider how this should be implemented when we add threads. + """Pseudo thread-local storage, for 'space.threadlocals'. + This is not really thread-local at all; the intention is that the PyPy + implementation of the 'thread' module knows how to provide a real + implementation for this feature, and patches 'space.threadlocals' when + 'thread' is initialized. + """ + _value = None - def __init__(self): - self.executioncontext = None + def getvalue(self): + return self._value + + def setvalue(self, value): + self._value = value + + def yield_thread(self): + """Called from time to time between the interpretation of bytecodes. + Hook for threading models that require it.""" From arigo at codespeak.net Fri Aug 19 19:20:34 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Aug 2005 19:20:34 +0200 (CEST) Subject: [pypy-svn] r16174 - in pypy/dist/pypy/module/thread: . rpython rpython/test test Message-ID: <20050819172034.35F6E27B6C@code1.codespeak.net> Author: arigo Date: Fri Aug 19 19:20:21 2005 New Revision: 16174 Added: pypy/dist/pypy/module/thread/ (props changed) pypy/dist/pypy/module/thread/__init__.py (contents, props changed) pypy/dist/pypy/module/thread/app_thread.py (contents, props changed) pypy/dist/pypy/module/thread/gil.py (contents, props changed) pypy/dist/pypy/module/thread/os_local.py (contents, props changed) pypy/dist/pypy/module/thread/os_lock.py (contents, props changed) pypy/dist/pypy/module/thread/os_thread.py (contents, props changed) pypy/dist/pypy/module/thread/rpython/ (props changed) pypy/dist/pypy/module/thread/rpython/__init__.py (contents, props changed) pypy/dist/pypy/module/thread/rpython/exttable.py (contents, props changed) pypy/dist/pypy/module/thread/rpython/ll_thread.py (contents, props changed) pypy/dist/pypy/module/thread/rpython/test/ (props changed) pypy/dist/pypy/module/thread/rpython/test/__init__.py (contents, props changed) pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py (contents, props changed) pypy/dist/pypy/module/thread/test/ (props changed) pypy/dist/pypy/module/thread/test/__init__.py pypy/dist/pypy/module/thread/test/support.py (contents, props changed) pypy/dist/pypy/module/thread/test/test_local.py (contents, props changed) pypy/dist/pypy/module/thread/test/test_lock.py (contents, props changed) pypy/dist/pypy/module/thread/test/test_thread.py (contents, props changed) pypy/dist/pypy/module/thread/threadlocals.py (contents, props changed) Log: The 'thread' module implemented with OS threads and a Global Interpreter Lock (as in CPython). Must be selected with --usemodules=thread. Very occasionally, one test fails. Hard to figure out what's wrong :-( The GIL itself is further separated from the rest of the code, which is about using OS threads and locks. It's almost completely isolated in gil.py. The 'thread._local' class is much nicer than in CPython: thanks to the getdict() method on all w_ objects, we can do the "right thing" and have getdict() return a dictionary that depends on the current thread. No need to patch the __dict__ of the thread._local instance in __getattribute__, __setattr__ and __delattr__. Experimentally, the 'thread' module comes with its own rpython support in the 'rpython' submodule: it provides rpython support for interp-level thread.start_new_thread(), thread.get_ident(), thread.allocate_lock() and lock objects (the latter using the "external types" of the previous check-in). Added: pypy/dist/pypy/module/thread/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/__init__.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,28 @@ + +# Package initialisation +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + appleveldefs = { + 'exit': 'app_thread.exit', + 'exit_thread': 'app_thread.exit', # obsolete synonym + 'error': 'app_thread.error', + } + + interpleveldefs = { + 'start_new_thread': 'os_thread.start_new_thread', + 'get_ident': 'os_thread.get_ident', + 'allocate_lock': 'os_lock.allocate_lock', + 'allocate': 'os_lock.allocate_lock', # obsolete synonym + 'LockType': 'os_lock.getlocktype(space)', + '_local': 'os_local.getlocaltype(space)', + } + + def __init__(self, space, *args): + "NOT_RPYTHON: patches space.threadlocals to use real threadlocals" + from pypy.module.thread import gil + MixedModule.__init__(self, space, *args) + prev = space.threadlocals.getvalue() + space.threadlocals = gil.GILThreadLocals() + space.threadlocals.setvalue(prev) + space.threadlocals.enter_thread(space) # setup the main thread Added: pypy/dist/pypy/module/thread/app_thread.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/app_thread.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,7 @@ +class error(Exception): + pass + +def exit(): + """This is synonymous to ``raise SystemExit''. It will cause the current +thread to exit silently unless the exception is caught.""" + raise SystemExit Added: pypy/dist/pypy/module/thread/gil.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/gil.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,35 @@ +""" +Global Interpreter Lock. +""" + +# This module adds a global lock to an object space. +# If multiple threads try to execute simultaneously in this space, +# all but one will be blocked. The other threads get a chance to run +# from time to time, using the executioncontext's XXX + +import thread +from pypy.module.thread.threadlocals import OSThreadLocals + + +class GILThreadLocals(OSThreadLocals): + """A version of OSThreadLocals that enforces a GIL.""" + + def __init__(self): + self.GIL = thread.allocate_lock() + + def enter_thread(self, space): + "Notification that the current thread is just starting: grab the GIL." + self.GIL.acquire(True) + OSThreadLocals.enter_thread(self, space) + + def leave_thread(self, space): + "Notification that the current thread is stopping: release the GIL." + OSThreadLocals.leave_thread(self, space) + self.GIL.release() + + def yield_thread(self): + """Notification that the current thread is between two bytecodes: + release the GIL for a little while.""" + self.GIL.release() + # Other threads can run here + self.GIL.acquire(True) Added: pypy/dist/pypy/module/thread/os_local.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/os_local.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,69 @@ +import thread +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import TypeDef, interp2app +from pypy.interpreter.typedef import GetSetProperty, descr_get_dict +from pypy.interpreter.typedef import descr_set_dict +from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments + + +class Local(Wrappable): + """Thread-local data""" + + def __init__(self, space, initargs): + self.space = space + self.initargs = initargs + ident = thread.get_ident() + self.dicts = {ident: space.newdict([])} + + def getdict(self): + ident = thread.get_ident() + try: + w_dict = self.dicts[ident] + except KeyError: + # create a new dict for this thread + space = self.space + w_dict = self.dicts[ident] = space.newdict([]) + # call __init__ + try: + w_self = space.wrap(self) + w_type = self.getclass(space) + w_init = space.getattr(w_type, space.wrap("__init__")) + space.call_args(w_init, self.initargs.prepend(w_self)) + except: + # failed, forget w_dict and propagate the exception + del self.dicts[ident] + raise + # ready + space.threadlocals.atthreadexit(space, finish_thread, self) + return w_dict + + def setdict(self, space, w_dict): + if not space.is_true(space.isinstance(w_dict, space.w_dict)): + raise OperationError(space.w_TypeError, + space.wrap("setting dictionary to a non-dict")) + self.getdict() # force a dict to exist first + ident = thread.get_ident() + self.dicts[ident] = w_dict + + def descr_local__new__(space, w_subtype, __args__): + # XXX check __args__ + local = space.allocate_instance(Local, w_subtype) + Local.__init__(local, space, __args__) + return space.wrap(local) + +Local.typedef = TypeDef("thread._local", + __doc__ = "Thread-local data", + __new__ = interp2app(Local.descr_local__new__.im_func, + unwrap_spec=[ObjSpace, W_Root, Arguments]), + __dict__ = GetSetProperty(descr_get_dict, + descr_set_dict, cls=Local), + ) + +def getlocaltype(space): + return space.gettypeobject(Local.typedef) + + +def finish_thread(w_obj): + assert isinstance(w_obj, Local) + ident = thread.get_ident() + del w_obj.dicts[ident] Added: pypy/dist/pypy/module/thread/os_lock.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/os_lock.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,104 @@ +""" +Python locks, based on true threading locks provided by the OS. +""" + +import thread +from pypy.interpreter.error import OperationError +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.gateway import ObjSpace, interp2app +from pypy.interpreter.typedef import TypeDef + +# Force the declaration of the type 'thread.LockType' for RPython +import pypy.module.thread.rpython.exttable + + +##import sys +##def debug(msg, n): +## return +## tb = [] +## try: +## for i in range(1, 8): +## tb.append(sys._getframe(i).f_code.co_name) +## except: +## pass +## tb = ' '.join(tb) +## msg = '| %6d | %d %s | %s\n' % (thread.get_ident(), n, msg, tb) +## sys.stderr.write(msg) + + +class Lock(Wrappable): + "A wrappable box around an interp-level lock object." + + def __init__(self): + self.lock = thread.allocate_lock() + + def descr_lock_acquire(self, space, waitflag=1): + """Lock the lock. Without argument, this blocks if the lock is already +locked (even by the same thread), waiting for another thread to release +the lock, and return None once the lock is acquired. +With an argument, this will only block if the argument is true, +and the return value reflects whether the lock is acquired. +The blocking operation is not interruptible.""" + # XXX Usage of threadlocals.GIL in this function is considered hackish. + # Ideally, all GIL knowledge should be in gil.py. + mylock = self.lock + GIL = space.threadlocals.GIL + GIL.release() + result = mylock.acquire(bool(waitflag)) + GIL.acquire(True) + return space.newbool(result) + + def descr_lock_release(self, space): + """Release the lock, allowing another thread that is blocked waiting for +the lock to acquire the lock. The lock must be in the locked state, +but it needn't be locked by the same thread that unlocks it.""" + try: + self.lock.release() + except thread.error: + w_module = space.getbuiltinmodule('thread') + w_error = space.getattr(w_module, space.wrap('error')) + raise OperationError(w_error, space.wrap("release unlocked lock")) + + def descr_lock_locked(self, space): + """Return whether the lock is in the locked state.""" + if self.lock.acquire(False): + self.lock.release() + return space.w_False + else: + return space.w_True + + +descr_acquire = interp2app(Lock.descr_lock_acquire, + unwrap_spec=['self', ObjSpace, int]) +descr_release = interp2app(Lock.descr_lock_release, + unwrap_spec=['self', ObjSpace]) +descr_locked = interp2app(Lock.descr_lock_locked, + unwrap_spec=['self', ObjSpace]) + +Lock.typedef = TypeDef("thread.lock", + __doc__ = """\ +A lock object is a synchronization primitive. To create a lock, +call the thread.allocate_lock() function. Methods are: + +acquire() -- lock the lock, possibly blocking until it can be obtained +release() -- unlock of the lock +locked() -- test whether the lock is currently locked + +A lock is not owned by the thread that locked it; another thread may +unlock it. A thread attempting to lock a lock that it has already locked +will block until another thread unlocks it. Deadlocks may ensue.""", + acquire = descr_acquire, + release = descr_release, + locked = descr_locked, + # Obsolete synonyms + acquire_lock = descr_acquire, + release_lock = descr_release, + locked_lock = descr_locked, + ) + + +def allocate_lock(space): + return space.wrap(Lock()) + +def getlocktype(space): + return space.gettypeobject(Lock.typedef) Added: pypy/dist/pypy/module/thread/os_thread.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/os_thread.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,63 @@ +""" +Thread support based on OS-level threads. +""" + +import thread +from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import NoneNotWrapped +from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments + +# Force the declaration of thread.start_new_thread() & co. for RPython +import pypy.module.thread.rpython.exttable + + +class Bootstrapper: + def bootstrap(self): + space = self.space + w_callable = self.w_callable + args = self.args + space.threadlocals.enter_thread(space) + try: + try: + space.call_args(w_callable, args) + except OperationError, e: + if not e.match(space, space.w_SystemExit): + ident = thread.get_ident() + where = 'thread %d started by' % ident + e.write_unraisable(space, where, w_callable) + e.clear(space) + finally: + # clean up space.threadlocals to remove the ExecutionContext + # entry corresponding to the current thread + space.threadlocals.leave_thread(space) + + +def start_new_thread(space, w_callable, w_args, w_kwargs=NoneNotWrapped): + """Start a new thread and return its identifier. The thread will call the +function with positional arguments from the tuple args and keyword arguments +taken from the optional dictionary kwargs. The thread exits when the +function returns; the return value is ignored. The thread will also exit +when the function raises an unhandled exception; a stack trace will be +printed unless the exception is SystemExit.""" + # XXX check that w_callable is callable + # XXX check that w_args is a tuple + # XXX check that w_kwargs is a dict + args = Arguments.frompacked(space, w_args, w_kwargs) + boot = Bootstrapper() + boot.space = space + boot.w_callable = w_callable + boot.args = args + ident = thread.start_new_thread(Bootstrapper.bootstrap, (boot,)) + return space.wrap(ident) + + +def get_ident(space): + """Return a non-zero integer that uniquely identifies the current thread +amongst other threads that exist simultaneously. +This may be used to identify per-thread resources. +Even though on some platforms threads identities may appear to be +allocated consecutive numbers starting at 1, this behavior should not +be relied upon, and the number should be seen purely as a magic cookie. +A thread's identity may be reused for another thread after it exits.""" + ident = thread.get_ident() + return space.wrap(ident) Added: pypy/dist/pypy/module/thread/rpython/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/rpython/__init__.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/module/thread/rpython/exttable.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/rpython/exttable.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,24 @@ +""" +Annotation support for interp-level lock objects. +""" + +import thread +from pypy.rpython.extfunctable import declare, declaretype + +module = 'pypy.module.thread.rpython.ll_thread' + +# ____________________________________________________________ +# The external type thread.LockType + +declaretype(thread.LockType, + "ThreadLock", + acquire = (bool, '%s/acquire_lock' % module), + release = (type(None), '%s/release_lock' % module), + ) + +# ____________________________________________________________ +# Built-in functions needed in the rtyper + +declare(thread.start_new_thread, int, '%s/start_new_thread' % module) +declare(thread.get_ident, int, '%s/get_ident' % module) +declare(thread.allocate_lock, thread.LockType, '%s/allocate_lock' % module) Added: pypy/dist/pypy/module/thread/rpython/ll_thread.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/rpython/ll_thread.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,37 @@ +""" +Dummy low-level implementations for the external functions of the 'thread' +module. +""" + +import thread +from pypy.rpython.module.support import from_rexternalobj, to_rexternalobj + +def ll_thread_start_new_thread(funcptr, argtuple): + # wrapper around ll_thread_start, to extract the single argument + # from the argtuple. + argument = argtuple.item0 # expects a single argument + return ll_thread_start(funcptr, argument) + +def ll_thread_start(funcptr, argument): + return thread.start_new_thread(funcptr, (argument,)) +ll_thread_start.suggested_primitive = True + +def ll_thread_get_ident(): + return thread.get_ident() +ll_thread_get_ident.suggested_primitive = True + + +def ll_thread_allocate_lock(): + lock = thread.allocate_lock() + return to_rexternalobj(lock) +ll_thread_allocate_lock.suggested_primitive = True + +def ll_thread_acquire_lock(lockptr, waitflag): + lock = from_rexternalobj(lockptr) + return lock.acquire(waitflag) +ll_thread_acquire_lock.suggested_primitive = True + +def ll_thread_release_lock(lockptr): + lock = from_rexternalobj(lockptr) + lock.release() +ll_thread_release_lock.suggested_primitive = True Added: pypy/dist/pypy/module/thread/rpython/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/rpython/test/__init__.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,25 @@ +import thread +import pypy.module.thread.rpython.exttable # for declare()/declaretype() +from pypy.module.thread.rpython.ll_thread import * +from pypy.translator.annrpython import RPythonAnnotator +from pypy.rpython.test.test_llinterp import interpret + + +def test_annotate_lock(): + def fn(): + return thread.allocate_lock().acquire(False) + a = RPythonAnnotator() + s = a.build_types(fn, []) + # result should be a boolean + assert s.knowntype == bool + +def test_lock(): + def fn(): + l = thread.allocate_lock() + ok1 = l.acquire(True) + ok2 = l.acquire(False) + l.release() + ok3 = l.acquire(False) + return ok1 and not ok2 and ok3 + res = interpret(fn, []) + assert res is True Added: pypy/dist/pypy/module/thread/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/test/__init__.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/module/thread/test/support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/test/support.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,28 @@ +import py + +class GenericTestThread: + + def setup_class(cls): + space = cls.space + if "thread" not in space.options.usemodules: + py.test.skip("--usemodules=thread option not provided") + + cls.w_waitfor = space.appexec([], """(): + import time + def waitfor(expr, timeout=10.0): + limit = time.time() + timeout + while time.time() <= limit: + time.sleep(0.005) + if expr(): + return + print '*** timed out ***' + return waitfor + """) + cls.w_busywait = space.appexec([], """(): + import time + def busywait(t): + limit = time.time() + t + while time.time() <= limit: + time.sleep(0.005) + return busywait + """) Added: pypy/dist/pypy/module/thread/test/test_local.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/test/test_local.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,73 @@ +from pypy.module.thread.test.support import GenericTestThread + + +class AppTestLocal(GenericTestThread): + + def test_local(self): + import thread + from thread import _local as tlsobject + freed = [] + class X: + def __del__(self): + freed.append(1) + + ok = [] + TLS1 = tlsobject() + TLS2 = tlsobject() + TLS1.aa = "hello" + def f(i): + success = False + try: + a = TLS1.aa = i + b = TLS1.bbb = X() + c = TLS2.cccc = i*3 + d = TLS2.ddddd = X() + self.busywait(0.05) + assert TLS1.aa == a + assert TLS1.bbb is b + assert TLS2.cccc == c + assert TLS2.ddddd is d + success = True + finally: + ok.append(success) + for i in range(20): + thread.start_new_thread(f, (i,)) + self.waitfor(lambda: len(ok) == 20, timeout=30.0) + assert ok == 20*[True] # see stdout/stderr for failures in the threads + + self.waitfor(lambda: len(freed) >= 40) + assert len(freed) == 40 + # in theory, all X objects should have been freed by now. Note that + # Python's own thread._local objects suffer from the very same "bug" that + # tls.py showed originally, and leaves len(freed)==38: the last thread's + # __dict__ remains stored in the TLS1/TLS2 instances, although it is not + # really accessible any more. + + assert TLS1.aa == "hello" + + + def test_local_init(self): + import thread + feedback = [] + seen = {} + + class X(thread._local): + def __init__(self, n): + assert n == 42 + self.tag = len(feedback) + feedback.append(1) + + x = X(42) + assert x.tag == 0 + assert feedback == [1] + def f(): + seen[x.tag] = True + for i in range(5): + thread.start_new_thread(f, ()) + self.waitfor(lambda: len(seen) == 5, timeout=20.0) + assert seen == {1: True, + 2: True, + 3: True, + 4: True, + 5: True} + assert len(feedback) == 6 Added: pypy/dist/pypy/module/thread/test/test_lock.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/test/test_lock.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,29 @@ +from pypy.module.thread.test.support import GenericTestThread + + +class AppTestLock(GenericTestThread): + + def test_lock(self): + import thread + lock = thread.allocate_lock() + assert type(lock) is thread.LockType + assert lock.locked() is False + raises(thread.error, lock.release) + assert lock.locked() is False + lock.acquire() + assert lock.locked() is True + lock.release() + assert lock.locked() is False + raises(thread.error, lock.release) + assert lock.locked() is False + feedback = [] + lock.acquire() + def f(): + self.busywait(0.25) + feedback.append(42) + lock.release() + assert lock.locked() is True + thread.start_new_thread(f, ()) + lock.acquire() + assert lock.locked() is True + assert feedback == [42] Added: pypy/dist/pypy/module/thread/test/test_thread.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/test/test_thread.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,128 @@ +from pypy.module.thread.test.support import GenericTestThread + + +class AppTestThread(GenericTestThread): + + def test_start_new_thread(self): + import thread + feedback = [] + please_start = [] + def f(x, y, z): + self.waitfor(lambda: please_start) + feedback.append(42) + thread.start_new_thread(f, (1, 2), {'z': 3}) + assert feedback == [] # still empty + please_start.append(1) # trigger + self.waitfor(lambda: feedback) + assert feedback == [42] + + def test_get_ident(self): + import thread + ident = thread.get_ident() + feedback = [] + def f(): + feedback.append(thread.get_ident()) + ident2 = thread.start_new_thread(f, ()) + assert ident2 != ident + assert ident == thread.get_ident() + self.waitfor(lambda: feedback) + assert feedback == [ident2] + + def test_sys_getframe(self): + # this checks that each thread gets its own ExecutionContext. + def main(): + import thread, sys + def dump_frames(feedback): + f = sys._getframe() + for i in range(3): + if f is None: + feedback.append(None) + else: + feedback.append(f.f_code.co_name) + self.busywait(0.04) + assert f is sys._getframe(i) + f = f.f_back + def dummyfn(feedback): + dump_frames(feedback) + feedback = [] + dummyfn(feedback) + assert feedback == ['dump_frames', 'dummyfn', 'main'] + feedbacks = [] + for i in range(3): + feedback = [] + thread.start_new_thread(dummyfn, (feedback,)) + feedbacks.append(feedback) + expected = 3*[['dump_frames', 'dummyfn', None]] # without 'main' + self.waitfor(lambda: feedbacks == expected) + assert feedbacks == expected + main() + + def test_thread_exit(self): + import thread, sys, StringIO + def fn1(): + thread.exit() + def fn2(): + raise SystemExit + def fn3(): + raise ValueError("hello world") + prev = sys.stderr + try: + sys.stderr = StringIO.StringIO() + thread.start_new_thread(fn1, ()) + thread.start_new_thread(fn2, ()) + self.busywait(0.2) # time for the threads to finish + assert sys.stderr.getvalue() == '' + + sys.stderr = StringIO.StringIO() + thread.start_new_thread(fn3, ()) + self.waitfor(lambda: "ValueError" in sys.stderr.getvalue()) + result = sys.stderr.getvalue() + assert "ValueError" in result + assert "hello world" in result + finally: + sys.stderr = prev + + def test_perthread_excinfo(self): + import thread, sys + done = [] + def fn1(n): + success = False + try: + caught = False + try: + try: + {}[n] + except KeyError: + self.busywait(0.05) + caught = True + raise + except KeyError: + self.busywait(0.05) + assert caught + etype, evalue, etb = sys.exc_info() + assert etype is KeyError + assert evalue.args[0] == n + success = True + finally: + done.append(success) + for i in range(20): + thread.start_new_thread(fn1, (i,)) + self.waitfor(lambda: len(done) == 20) + assert done == 20*[True] # see stderr for failures in the threads + + def test_no_corruption(self): + import thread + lst = [] + done_marker = [] + def f(x, done): + for j in range(40): + lst.insert(0, x+j) # all threads trying to modify the same list + done.append(True) + for i in range(0, 120, 40): + done = [] + thread.start_new_thread(f, (i, done)) + done_marker.append(done) + for done in done_marker: + self.waitfor(lambda: done, timeout=20.0) + assert done # see stderr for failures in threads + assert sorted(lst) == range(120) Added: pypy/dist/pypy/module/thread/threadlocals.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/threadlocals.py Fri Aug 19 19:20:21 2005 @@ -0,0 +1,45 @@ +import thread + + +class OSThreadLocals: + """Thread-local storage for OS-level threads. + For memory management, this version depends on explicit notification when + a thread finishes. This works as long as the thread was started by + os_thread.bootstrap().""" + + _valuedict = {} # {thread_ident: ExecutionContext()} + + def getvalue(self): + ident = thread.get_ident() + return self._valuedict.get(ident, None) + + def setvalue(self, value): + ident = thread.get_ident() + self._valuedict[ident] = value + + def enter_thread(self, space): + "Notification that the current thread is just starting." + ec = space.getexecutioncontext() + ec.thread_exit_funcs = [] + + def leave_thread(self, space): + "Notification that the current thread is about to stop." + try: + ec = space.getexecutioncontext() + while ec.thread_exit_funcs: + exit_func, w_obj = ec.thread_exit_funcs.pop() + exit_func(w_obj) + finally: + ident = thread.get_ident() + try: + del self._valuedict[ident] + except KeyError: + pass + + def yield_thread(self): + """Notification that the current thread is between two bytecodes + (so that it's a good time to yield some time to other threads).""" + + def atthreadexit(self, space, exit_func, w_obj): + ec = space.getexecutioncontext() + ec.thread_exit_funcs.append((exit_func, w_obj)) From pedronis at codespeak.net Fri Aug 19 19:34:00 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 19 Aug 2005 19:34:00 +0200 (CEST) Subject: [pypy-svn] r16175 - in pypy/dist/pypy: annotation rpython rpython/test Message-ID: <20050819173400.72EB927B6C@code1.codespeak.net> Author: pedronis Date: Fri Aug 19 19:33:57 2005 New Revision: 16175 Modified: pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/rpython/lltype.py pypy/dist/pypy/rpython/normalizecalls.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rclass.py pypy/dist/pypy/rpython/rmodel.py pypy/dist/pypy/rpython/test/test_lltype.py pypy/dist/pypy/rpython/test/test_nongc.py pypy/dist/pypy/rpython/test/test_rtyper.py Log: support for _alloc_flavor_ in class definitions to allow non-gc allocation strategies for classes. introduced a flavor (defaults to 'gc') argument to malloc, and flavor_malloc free_non_gc_object ops non-gc is assumed if the flavor string doesn't start with 'gc'. In that case a Struct and not a GcStruct will be used for the instances. There's a common base instance object for such non-gc classes, using the rclass.NONGCOBJECT Struct. Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Fri Aug 19 19:33:57 2005 @@ -337,6 +337,15 @@ BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info +#________________________________ +# non-gc objects + +def robjmodel_free_non_gc_object(obj): + pass + +BUILTIN_ANALYZERS[pypy.rpython.objectmodel.free_non_gc_object] = ( + robjmodel_free_non_gc_object) + #_________________________________ # memory address Modified: pypy/dist/pypy/rpython/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltype.py (original) +++ pypy/dist/pypy/rpython/lltype.py Fri Aug 19 19:33:57 2005 @@ -348,7 +348,7 @@ def _example(self): o = self.TO._container_example() - return _ptr(self, o, immortal=True) + return _ptr(self, o, solid=True) # ____________________________________________________________ @@ -462,7 +462,7 @@ class _ptr(object): __slots__ = ('_TYPE', '_T', - '_weak', '_immortal', + '_weak', '_solid', '_obj0', '__weakref__') def _set_TYPE(self, TYPE): @@ -474,8 +474,8 @@ def _set_weak(self, weak): _ptr._weak.__set__(self, weak) - def _set_immortal(self, immortal): - _ptr._immortal.__set__(self, immortal) + def _set_solid(self, solid): + _ptr._solid.__set__(self, solid) def _set_obj0(self, obj): _ptr._obj0.__set__(self, obj) @@ -483,11 +483,11 @@ def _needsgc(self): return self._TYPE._needsgc() # xxx other rules? - def __init__(self, TYPE, pointing_to, immortal=False): + def __init__(self, TYPE, pointing_to, solid=False): self._set_TYPE(TYPE) self._set_T(TYPE.TO) self._set_weak(False) - self._setobj(pointing_to, immortal) + self._setobj(pointing_to, solid) def __eq__(self, other): if not isinstance(other, _ptr): @@ -508,15 +508,15 @@ # _setobj, _getobj and _obj0 are really _internal_ implementations details of _ptr, # use _obj if necessary instead ! - def _setobj(self, pointing_to, immortal=False): + def _setobj(self, pointing_to, solid=False): if pointing_to is None: obj0 = None - elif immortal or isinstance(self._T, (GC_CONTAINER, FuncType)): + elif solid or isinstance(self._T, (GC_CONTAINER, FuncType)): obj0 = pointing_to else: self._set_weak(True) obj0 = weakref.ref(pointing_to) - self._set_immortal(immortal) + self._set_solid(solid) self._set_obj0(obj0) def _getobj(self): @@ -811,16 +811,21 @@ return "pyobject %s" % (super(_pyobject, self).__str__(),) -def malloc(T, n=None, immortal=False): +def malloc(T, n=None, flavor='gc', immortal=False): if isinstance(T, Struct): o = _struct(T, n) elif isinstance(T, Array): o = _array(T, n) else: raise TypeError, "malloc for Structs and Arrays only" - if not isinstance(T, GC_CONTAINER) and not immortal: - raise TypeError, "malloc of a non-GC non-immortal structure" - return _ptr(Ptr(T), o, immortal) + if not isinstance(T, GC_CONTAINER) and not immortal and flavor.startswith('gc'): + raise TypeError, "gc flavor malloc of a non-GC non-immortal structure" + solid = immortal or not flavor.startswith('gc') # immortal or non-gc case + return _ptr(Ptr(T), o, solid) + +def flavored_malloc(flavor, T, n=None): # avoids keyword argument usage + return malloc(T, n, flavor=flavor) + def functionptr(TYPE, name, **attrs): if not isinstance(TYPE, FuncType): @@ -839,7 +844,7 @@ if not isinstance(TYPE, OpaqueType): raise TypeError, "opaqueptr() for OpaqueTypes only" o = _opaque(TYPE, _name=name, **attrs) - return _ptr(Ptr(TYPE), o, immortal=attrs.get('immortal', True)) + return _ptr(Ptr(TYPE), o, solid=attrs.get('immortal', True)) def pyobjectptr(obj): o = _pyobject(obj) Modified: pypy/dist/pypy/rpython/normalizecalls.py ============================================================================== --- pypy/dist/pypy/rpython/normalizecalls.py (original) +++ pypy/dist/pypy/rpython/normalizecalls.py Fri Aug 19 19:33:57 2005 @@ -6,7 +6,7 @@ from pypy.annotation import model as annmodel from pypy.tool.sourcetools import has_varargs, valid_identifier from pypy.tool.sourcetools import func_with_new_name -from pypy.rpython.rmodel import TyperError +from pypy.rpython.rmodel import TyperError, needsgc from pypy.rpython.objectmodel import instantiate @@ -325,7 +325,8 @@ def create_instantiate_functions(annotator): # build the 'instantiate() -> instance of C' functions for the vtables for cls, classdef in annotator.getuserclasses().items(): - create_instantiate_function(annotator, cls, classdef) + if needsgc(classdef): # only gc-case + create_instantiate_function(annotator, cls, classdef) def create_instantiate_function(annotator, cls, classdef): def my_instantiate(): Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Fri Aug 19 19:33:57 2005 @@ -26,6 +26,6 @@ def free_non_gc_object(obj): - assert getattr(obj.__class__, "_alloc_flavor_", False) == "", "trying to free regular object" + assert not getattr(obj.__class__, "_alloc_flavor_", 'gc').startswith('gc'), "trying to free gc object" obj.__dict__ = {} obj.__class__ = FREED_OBJECT Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Fri Aug 19 19:33:57 2005 @@ -141,10 +141,11 @@ vlist = hop.inputarg(rlist, arg=0) cnone = hop.inputconst(rlist, None) return hop.genop('ptr_ne', [vlist, cnone], resulttype=lltype.Bool) - - instance_repr = rclass.getinstancerepr(hop.rtyper, None) + class_repr = rclass.get_type_repr(hop.rtyper) - + assert isinstance(hop.args_r[0], rclass.InstanceRepr) + instance_repr = hop.args_r[0].common_repr() + v_obj, v_cls = hop.inputargs(instance_repr, class_repr) return hop.gendirectcall(rclass.ll_isinstance, v_obj, v_cls) @@ -318,3 +319,15 @@ BUILTIN_TYPER[lladdress.raw_malloc] = rtype_raw_malloc BUILTIN_TYPER[lladdress.raw_free] = rtype_raw_free BUILTIN_TYPER[lladdress.raw_memcopy] = rtype_raw_memcopy + +# _________________________________________________________________ +# non-gc objects + +def rtype_free_non_gc_object(hop): + vinst, = hop.inputargs(hop.args_r[0]) + flavor = hop.args_r[0].getflavor() + assert not flavor.startswith('gc') + cflavor = hop.inputconst(lltype.Void, flavor) + return hop.genop('free_non_gc_object', [cflavor, vinst]) + +BUILTIN_TYPER[objectmodel.free_non_gc_object] = rtype_free_non_gc_object Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Fri Aug 19 19:33:57 2005 @@ -2,7 +2,7 @@ from pypy.annotation.pairtype import pairtype, pair from pypy.annotation import model as annmodel from pypy.annotation.classdef import isclassdef -from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning +from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning, needsgc from pypy.rpython.lltype import ForwardReference, GcForwardReference from pypy.rpython.lltype import Ptr, Struct, GcStruct, malloc from pypy.rpython.lltype import cast_pointer, castable, nullptr @@ -39,6 +39,7 @@ # ... // extra instance attributes # } # +# there's also a nongcobject OBJECT_VTABLE = ForwardReference() TYPEPTR = Ptr(OBJECT_VTABLE) @@ -49,6 +50,9 @@ ('rtti', Ptr(RuntimeTypeInfo)), ('name', Ptr(Array(Char))), ('instantiate', Ptr(FuncType([], OBJECTPTR))))) +# non-gc case +NONGCOBJECT = Struct('nongcobject', ('typeptr', TYPEPTR)) +NONGCOBJECTPTR = Ptr(OBJECT) def getclassrepr(rtyper, classdef): try: @@ -69,16 +73,17 @@ rtyper.add_pendingsetup(result) return result -def getinstancerepr(rtyper, classdef): +def getinstancerepr(rtyper, classdef, nogc=False): + does_need_gc = needsgc(classdef, nogc) try: - result = rtyper.instance_reprs[classdef] + result = rtyper.instance_reprs[classdef, does_need_gc] except KeyError: if classdef and classdef.cls is Exception: # see getclassrepr() - result = getinstancerepr(rtyper, None) + result = getinstancerepr(rtyper, None, nogc=False) else: - result = InstanceRepr(rtyper,classdef) - rtyper.instance_reprs[classdef] = result + result = InstanceRepr(rtyper,classdef, does_need_gc=does_need_gc) + rtyper.instance_reprs[classdef, does_need_gc] = result rtyper.add_pendingsetup(result) return result @@ -217,7 +222,8 @@ vtable.parenttypeptr = rsubcls.rbase.getvtable() rinstance = getinstancerepr(self.rtyper, rsubcls.classdef) rinstance.setup() - vtable.rtti = getRuntimeTypeInfo(rinstance.object_type) + if rinstance.needsgc: # only gc-case + vtable.rtti = getRuntimeTypeInfo(rinstance.object_type) if rsubcls.classdef is None: name = 'object' else: @@ -338,15 +344,23 @@ class InstanceRepr(Repr): - def __init__(self, rtyper, classdef): + def __init__(self, rtyper, classdef, does_need_gc=True): self.rtyper = rtyper self.classdef = classdef if classdef is None: - self.object_type = OBJECT + if does_need_gc: + self.object_type = OBJECT + else: + self.object_type = NONGCOBJECT else: - self.object_type = GcForwardReference() + if does_need_gc: + self.object_type = GcForwardReference() + else: + self.object_type = ForwardReference() + self.prebuiltinstances = {} # { id(x): (x, _ptr) } self.lowleveltype = Ptr(self.object_type) + self.needsgc = does_need_gc def __repr__(self): if self.classdef is None: @@ -383,9 +397,14 @@ fields['_hash_cache_'] = 'hash_cache', rint.signed_repr llfields.append(('hash_cache', Signed)) - self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef) + self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, not self.needsgc) self.rbase.setup() - object_type = GcStruct(self.classdef.cls.__name__, + if self.needsgc: + MkStruct = GcStruct + else: + MkStruct = Struct + + object_type = MkStruct(self.classdef.cls.__name__, ('super', self.rbase.object_type), *llfields) self.object_type.become(object_type) @@ -393,12 +412,19 @@ allinstancefields.update(fields) self.fields = fields self.allinstancefields = allinstancefields - attachRuntimeTypeInfo(self.object_type) + if self.needsgc: # only gc-case + attachRuntimeTypeInfo(self.object_type) def _setup_repr_final(self): - self.rtyper.attachRuntimeTypeInfoFunc(self.object_type, - ll_runtime_type_info, - OBJECT) + if self.needsgc: # only gc-case + self.rtyper.attachRuntimeTypeInfoFunc(self.object_type, + ll_runtime_type_info, + OBJECT) + def common_repr(self): # -> object or nongcobject reprs + return getinstancerepr(self.rtyper, None, nogc=not self.needsgc) + + def getflavor(self): + return getattr(self.classdef.cls, '_alloc_flavor_', 'gc') def convert_const(self, value): if value is None: @@ -423,7 +449,7 @@ return self.prebuiltinstances[id(value)][1] except KeyError: self.setup() - result = malloc(self.object_type) + result = malloc(self.object_type, flavor=self.getflavor()) # pick flavor self.prebuiltinstances[id(value)] = value, result self.initialize_prebuilt_instance(value, classdef, result) return result @@ -500,9 +526,16 @@ def new_instance(self, llops): """Build a new instance, without calling __init__.""" + mallocop = 'malloc' ctype = inputconst(Void, self.object_type) - vptr = llops.genop('malloc', [ctype], - resulttype = Ptr(self.object_type)) + vlist = [ctype] + if self.classdef is not None: + flavor = self.getflavor() + if flavor != 'gc': # not defalut flavor + mallocop = 'flavored_malloc' + vlist = [inputconst(Void, flavor)] + vlist + vptr = llops.genop(mallocop, vlist, + resulttype = Ptr(self.object_type)) # xxx flavor ctypeptr = inputconst(TYPEPTR, self.rclass.getvtable()) self.setfield(vptr, '__class__', ctypeptr, llops) # initialize instance attributes from their defaults from the class @@ -561,7 +594,7 @@ vinst, = hop.inputargs(self) return hop.genop('ptr_nonzero', [vinst], resulttype=Bool) - def ll_str(i, r): + def ll_str(i, r): # doesn't work for non-gc classes! instance = cast_pointer(OBJECTPTR, i) from pypy.rpython import rstr nameLen = len(instance.typeptr.name) @@ -601,9 +634,11 @@ def rtype_is_((r_ins1, r_ins2), hop): if r_ins1.classdef is None or r_ins2.classdef is None: basedef = None + nogc = not (r_ins1.needsgc and r_ins2.needsgc) else: basedef = r_ins1.classdef.commonbase(r_ins2.classdef) - r_ins = getinstancerepr(r_ins1.rtyper, basedef) + nogc = False + r_ins = getinstancerepr(r_ins1.rtyper, basedef, nogc=nogc) return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop) rtype_eq = rtype_is_ @@ -630,9 +665,11 @@ # # Low-level implementation of operations on classes and instances +# doesn't work for non-gc stuff! def ll_cast_to_object(obj): return cast_pointer(OBJECTPTR, obj) +# doesn't work for non-gc stuff! def ll_type(obj): return cast_pointer(OBJECTPTR, obj).typeptr @@ -643,10 +680,10 @@ subcls = subcls.parenttypeptr return True -def ll_isinstance(obj, cls): +def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT if not obj: return False - obj_cls = ll_type(obj) + obj_cls = obj.typeptr return ll_issubclass(obj_cls, cls) def ll_runtime_type_info(obj): Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Fri Aug 19 19:33:57 2005 @@ -297,3 +297,10 @@ def warning(msg): ansi_print("*** WARNING: %s" % (msg,), esc="31") # RED + + +def needsgc(classdef, nogc=False): + if classdef is None: + return not nogc + else: + return getattr(classdef.cls, '_alloc_flavor_', 'gc').startswith('gc') Modified: pypy/dist/pypy/rpython/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_lltype.py (original) +++ pypy/dist/pypy/rpython/test/test_lltype.py Fri Aug 19 19:33:57 2005 @@ -389,3 +389,11 @@ s1.sub.x = 1 assert runtime_type_info(s1.sub) == getRuntimeTypeInfo(S1) +def test_flavor_malloc(): + S = Struct('s', ('x', Signed)) + py.test.raises(TypeError, malloc, S) + p = malloc(S, flavor="raw") + assert typeOf(p).TO == S + assert not isweak(p, S) + + Modified: pypy/dist/pypy/rpython/test/test_nongc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_nongc.py (original) +++ pypy/dist/pypy/rpython/test/test_nongc.py Fri Aug 19 19:33:57 2005 @@ -25,7 +25,129 @@ py.test.raises(RuntimeError, "t.a") py.test.raises(AssertionError, "free_non_gc_object(TestClass2())") -def DONOTtest_rtype_free_non_gc_object(): +def test_alloc_flavor(): + class A: + _alloc_flavor_ = "raw" + def f(): + return A() + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, []) + assert s.knowntype == A + rtyper = RPythonTyper(a) + rtyper.specialize() + Adef = rtyper.annotator.getuserclasses()[A] + assert (Adef, False) in rtyper.instance_reprs + assert (Adef, True) not in rtyper.instance_reprs + +def test_alloc_flavor_subclassing(): + class A: + _alloc_flavor_ = "raw" + class B(A): + def __init__(self, a): + self.a = a + def f(): + return B(0) + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, []) + assert s.knowntype == B + rtyper = RPythonTyper(a) + rtyper.specialize() + Adef = rtyper.annotator.getuserclasses()[A] + assert (Adef, False) in rtyper.instance_reprs + assert (Adef, True) not in rtyper.instance_reprs + Bdef = rtyper.annotator.getuserclasses()[B] + assert (Bdef, False) in rtyper.instance_reprs + assert (Bdef, True) not in rtyper.instance_reprs + +def test_unsupported(): + class A: + _alloc_flavor_ = "raw" + def f(): + return str(A()) + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, []) + assert s.knowntype == str + rtyper = RPythonTyper(a) + py.test.raises(TypeError,rtyper.specialize) # results in an invalid cast + +def test_isinstance(): + class A: + _alloc_flavor_ = "raw" + class B(A): + pass + class C(B): + pass + + def f(i): + if i == 0: + o = None + elif i == 1: + o = A() + elif i == 2: + o = B() + else: + o = C() + return 100*isinstance(o, A)+10*isinstance(o, B)+1*isinstance(o ,C) + + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, [int]) + assert s.knowntype == int + rtyper = RPythonTyper(a) + rtyper.specialize() +## res = interpret(f, [1]) +## assert res == 100 +## res = interpret(f, [2]) +## assert res == 110 +## res = interpret(f, [3]) +## assert res == 111 + +## res = interpret(f, [0]) +## assert res == 0 + + +def test_is(): + class A: + _alloc_flavor_ = "raw" + pass + class B(A): pass + class C: pass + def f(i): + a = A() + b = B() + c = C() + d = None + e = None + if i == 0: + d = a + elif i == 1: + d = b + elif i == 2: + e = c + return (0x0001*(a is b) | 0x0002*(a is c) | 0x0004*(a is d) | + 0x0008*(a is e) | 0x0010*(b is c) | 0x0020*(b is d) | + 0x0040*(b is e) | 0x0080*(c is d) | 0x0100*(c is e) | + 0x0200*(d is e)) + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, [int]) + assert s.knowntype == int + rtyper = RPythonTyper(a) + rtyper.specialize() +## res = interpret(f, [0]) +## assert res == 0x0004 +## res = interpret(f, [1]) +## assert res == 0x0020 +## res = interpret(f, [2]) +## assert res == 0x0100 +## res = interpret(f, [3]) +## assert res == 0x0200 + + +def test_rtype__nongc_object(): class TestClass(object): _alloc_flavor_ = "" def __init__(self, a): @@ -36,7 +158,7 @@ return 42 def malloc_and_free(a): ci = TestClass(a) - b = ci.a + b = ci.method1() free_non_gc_object(ci) return b a = RPythonAnnotator() Modified: pypy/dist/pypy/rpython/test/test_rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rtyper.py (original) +++ pypy/dist/pypy/rpython/test/test_rtyper.py Fri Aug 19 19:33:57 2005 @@ -3,6 +3,7 @@ from pypy.rpython.lltype import * from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.rtyper import RPythonTyper +from pypy.rpython import rmodel import py def setup_module(mod): @@ -107,3 +108,28 @@ a.translator.specialize() assert [vT.concretetype for vT in vTs] == [Void] * 3 + +def test_needsgc(): + class A: + pass + class B: + _alloc_flavor_ = "gc" + class R: + _alloc_flavor_ = "nongc" + class DummyClsDef: + def __init__(self, cls): + self.cls = cls + + assert rmodel.needsgc(DummyClsDef(A)) + assert rmodel.needsgc(DummyClsDef(A), nogc=True) + assert rmodel.needsgc(DummyClsDef(B)) + assert rmodel.needsgc(DummyClsDef(B), nogc=True) + assert not rmodel.needsgc(DummyClsDef(R)) + assert not rmodel.needsgc(DummyClsDef(R), nogc=False) + assert rmodel.needsgc(None) + assert rmodel.needsgc(None, nogc=False) + assert not rmodel.needsgc(None, nogc=True) + + + + From arigo at codespeak.net Fri Aug 19 19:37:47 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Aug 2005 19:37:47 +0200 (CEST) Subject: [pypy-svn] r16176 - pypy/dist/pypy/translator Message-ID: <20050819173747.EFCF827B6C@code1.codespeak.net> Author: arigo Date: Fri Aug 19 19:37:45 2005 New Revision: 16176 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: Got on two machines a missing attribute in the pypy._cache package. Assuming it's a revision bump missing in geninterplevel -- this fixes the problem. Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Fri Aug 19 19:37:45 2005 @@ -77,7 +77,7 @@ import pypy # __path__ import py.path -GI_VERSION = '1.1.14' # bump this for substantial changes +GI_VERSION = '1.1.15' # bump this for substantial changes # ____________________________________________________________ try: From arigo at codespeak.net Fri Aug 19 19:43:55 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 19 Aug 2005 19:43:55 +0200 (CEST) Subject: [pypy-svn] r16177 - pypy/dist/pypy/module/_codecs Message-ID: <20050819174355.50BD627B6C@code1.codespeak.net> Author: arigo Date: Fri Aug 19 19:43:53 2005 New Revision: 16177 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: A note. Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Fri Aug 19 19:43:53 2005 @@ -281,6 +281,7 @@ res = ''.join(res) return res, len(res) # XXX escape_decode Check if this is right +# XXX needs error messages when the input is invalid def escape_decode(data,errors='strict'): """None """ @@ -311,9 +312,11 @@ res += '\a' elif data[i] == 'v': res += '\v' - elif data[i] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: + elif '0' <= data[i] <= '9': + # emulate a strange wrap-around behavior of CPython: + # \400 is the same as \000 because 0400 == 256 octal = data[i:i+3] - res += chr(int(octal,8)) + res += chr(int(octal,8) & 0xFF) i += 2 elif data[i] == 'x': hexa = data[i+1:i+3] From cfbolz at codespeak.net Fri Aug 19 20:25:58 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 19 Aug 2005 20:25:58 +0200 (CEST) Subject: [pypy-svn] r16180 - in pypy/dist/pypy/rpython: . test Message-ID: <20050819182558.041F527B7A@code1.codespeak.net> Author: cfbolz Date: Fri Aug 19 20:25:57 2005 New Revision: 16180 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/test/test_nongc.py Log: implementing flavored_malloc in the llinterpreter Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Aug 19 20:25:57 2005 @@ -5,6 +5,7 @@ from pypy.rpython import lltype from pypy.rpython.rmodel import getfunctionptr from pypy.rpython.memory import lladdress +from pypy.rpython.objectmodel import free_non_gc_object import math import py @@ -284,6 +285,10 @@ else: return self.llt.malloc(obj, size) + def op_flavored_malloc(self, flavor, obj): + assert isinstance(flavor, str) + return self.llt.malloc(obj, flavor=flavor) + def op_getfield(self, obj, field): assert isinstance(obj, self.llt._ptr) result = getattr(obj, field) Modified: pypy/dist/pypy/rpython/test/test_nongc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_nongc.py (original) +++ pypy/dist/pypy/rpython/test/test_nongc.py Fri Aug 19 20:25:57 2005 @@ -4,6 +4,7 @@ from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.objectmodel import free_non_gc_object +from pypy.rpython.test.test_llinterp import interpret def test_free_non_gc_object(): class TestClass(object): @@ -98,15 +99,14 @@ assert s.knowntype == int rtyper = RPythonTyper(a) rtyper.specialize() -## res = interpret(f, [1]) -## assert res == 100 -## res = interpret(f, [2]) -## assert res == 110 -## res = interpret(f, [3]) -## assert res == 111 - -## res = interpret(f, [0]) -## assert res == 0 + res = interpret(f, [1]) + assert res == 100 + res = interpret(f, [2]) + assert res == 110 + res = interpret(f, [3]) + assert res == 111 + res = interpret(f, [0]) + assert res == 0 def test_is(): @@ -148,14 +148,13 @@ def test_rtype__nongc_object(): + from pypy.rpython.memory.lladdress import address class TestClass(object): - _alloc_flavor_ = "" + _alloc_flavor_ = "raw" def __init__(self, a): self.a = a def method1(self): return self.a - def method2(self): - return 42 def malloc_and_free(a): ci = TestClass(a) b = ci.method1() @@ -167,3 +166,5 @@ assert isinstance(s, annmodel.SomeAddress) rtyper = RPythonTyper(a) rtyper.specialize() +## res = interpret(malloc_and_free, [address()]) +## assert res == address() From pedronis at codespeak.net Fri Aug 19 21:08:50 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 19 Aug 2005 21:08:50 +0200 (CEST) Subject: [pypy-svn] r16181 - in pypy/dist/pypy/rpython: . test Message-ID: <20050819190850.0351C27B7A@code1.codespeak.net> Author: pedronis Date: Fri Aug 19 21:08:49 2005 New Revision: 16181 Modified: pypy/dist/pypy/rpython/rclass.py pypy/dist/pypy/rpython/test/test_nongc.py Log: fixed is/_alloc_flavor_ bug Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Fri Aug 19 21:08:49 2005 @@ -632,12 +632,15 @@ return NotImplemented def rtype_is_((r_ins1, r_ins2), hop): + if r_ins1.needsgc != r_ins2.needsgc: + # obscure logic, the is can be true only if both are None + v_ins1, v_ins2 = hop.inputargs(r_ins1.common_repr(), r_ins2.common_repr()) + return hop.gendirectcall(ll_both_none, v_ins1, v_ins2) + nogc = not (r_ins1.needsgc and r_ins2.needsgc) if r_ins1.classdef is None or r_ins2.classdef is None: basedef = None - nogc = not (r_ins1.needsgc and r_ins2.needsgc) else: basedef = r_ins1.classdef.commonbase(r_ins2.classdef) - nogc = False r_ins = getinstancerepr(r_ins1.rtyper, basedef, nogc=nogc) return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop) @@ -647,6 +650,9 @@ v = rpair.rtype_eq(hop) return hop.genop("bool_not", [v], resulttype=Bool) +def ll_both_none(ins1, ins2): + return not ins1 and not ins2 + # ____________________________________________________________ def rtype_new_instance(rtyper, cls, llops): Modified: pypy/dist/pypy/rpython/test/test_nongc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_nongc.py (original) +++ pypy/dist/pypy/rpython/test/test_nongc.py Fri Aug 19 21:08:49 2005 @@ -108,13 +108,13 @@ res = interpret(f, [0]) assert res == 0 - def test_is(): class A: _alloc_flavor_ = "raw" pass class B(A): pass - class C: pass + class C: + _alloc_flavor_ = "raw" def f(i): a = A() b = B() @@ -137,17 +137,54 @@ assert s.knowntype == int rtyper = RPythonTyper(a) rtyper.specialize() -## res = interpret(f, [0]) -## assert res == 0x0004 -## res = interpret(f, [1]) -## assert res == 0x0020 -## res = interpret(f, [2]) -## assert res == 0x0100 -## res = interpret(f, [3]) -## assert res == 0x0200 + res = interpret(f, [0]) + assert res == 0x0004 + res = interpret(f, [1]) + assert res == 0x0020 + res = interpret(f, [2]) + assert res == 0x0100 + res = interpret(f, [3]) + assert res == 0x0200 +def test_is_mixing(): + class A: + _alloc_flavor_ = "raw" + pass + class B(A): pass + class C: + pass + def f(i): + a = A() + b = B() + c = C() + d = None + e = None + if i == 0: + d = a + elif i == 1: + d = b + elif i == 2: + e = c + return (0x0001*(a is b) | 0x0002*(a is c) | 0x0004*(a is d) | + 0x0008*(a is e) | 0x0010*(b is c) | 0x0020*(b is d) | + 0x0040*(b is e) | 0x0080*(c is d) | 0x0100*(c is e) | + 0x0200*(d is e)) + a = RPythonAnnotator() + #does not raise: + s = a.build_types(f, [int]) + assert s.knowntype == int + rtyper = RPythonTyper(a) + rtyper.specialize() + res = interpret(f, [0]) + assert res == 0x0004 + res = interpret(f, [1]) + assert res == 0x0020 + res = interpret(f, [2]) + assert res == 0x0100 + res = interpret(f, [3]) + assert res == 0x0200 -def test_rtype__nongc_object(): +def test_rtype_nongc_object(): from pypy.rpython.memory.lladdress import address class TestClass(object): _alloc_flavor_ = "raw" From hpk at codespeak.net Sat Aug 20 11:25:45 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 20 Aug 2005 11:25:45 +0200 (CEST) Subject: [pypy-svn] r16182 - pypy/extradoc/minute Message-ID: <20050820092545.F35D727B54@code1.codespeak.net> Author: hpk Date: Sat Aug 20 11:25:44 2005 New Revision: 16182 Added: pypy/extradoc/minute/pypy-sync-08-18-2005.txt Log: pypy-sync minutes from 18th August (also links to the new heidelberg-planning) Added: pypy/extradoc/minute/pypy-sync-08-18-2005.txt ============================================================================== --- (empty file) +++ pypy/extradoc/minute/pypy-sync-08-18-2005.txt Sat Aug 20 11:25:44 2005 @@ -0,0 +1,201 @@ +============================================= +pypy-sync developer meeting 18th August 2005 +============================================= + +Time & location: 1pm (30 minutes) at #pypy-sync + +Attendees:: + + Samuele Pedroni, + Carl Friedrich Bolz, + Armin Rigo + Anders Chrigstroem + Anders Lehmann + Michael Hudson (lurking) + Holger Krekel (minutes/moderation) + +Regular Topics +==================== + +- activity reports (3 prepared lines of info). + All Attendees submitted activity reports (see `IRC-Log`_ + at the end and 'LAST/NEXT/BLOCKERS' entries in particular) + +- resolve conflicts/blockers + No conflicts were discovered. + +Topics of the week +=================== + +More detailed Heidelberg Sprint Planning +------------------------------------------- + +The `Heidelberg sprint announcement`_ already listed +some topics which we discussed in more detail. +Samuele then prepared a first `heidelberg-planning`_ +document that we are going to use monday morning. + +.. _`Heidelberg sprint announcement`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/Heidelberg-sprint.html +.. _`heidelberg-planning`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/heidelberg-planning.html + +Closing +------------------ + +Holger closes the meeting in time at 13:30pm. + +.. _`IRC-log`: + +Here is the full IRC log:: + + **** BEGIN LOGGING AT Thu Aug 18 12:59:41 2005 + Aug 18 12:59:41 --> You are now talking on #pypy-sync + Aug 18 13:01:15 --> arigo (n=chatzill at d213-103-136-75.cust.tele2.ch) has joined #pypy-sync + Aug 18 13:02:19 --> mwh (n=user at 82-33-185-193.cable.ubr01.azte.blueyonder.co.uk) has joined #pypy-sync + Aug 18 13:02:49 (lurking again today) + Aug 18 13:03:16 --> aleale (n=andersle at clogs.dfki.uni-sb.de) has joined #pypy-sync + Aug 18 13:03:52 are we ready to start the meeting? + Aug 18 13:04:12 I am + Aug 18 13:04:16 --> arre (i=7355b7b7 at 1-1-5-33a.gfa.gbg.bostream.se) has joined #pypy-sync + Aug 18 13:04:25 hey arre + Aug 18 13:04:37 yes + Aug 18 13:04:53 pedronis: are you there as well? + Aug 18 13:04:59 yes + Aug 18 13:05:04 yes + Aug 18 13:05:11 great, then here is the agenda: + Aug 18 13:05:16 I'm still on vacation, coincidentally i was near a computer when the meeting should start :) + Aug 18 13:05:16 - activity reports (3 prepared lines of info). + Aug 18 13:05:16 - resolve conflicts/blockers + Aug 18 13:05:16 *Topics of the week* + Aug 18 13:05:16 - Preplanning Heidelberg sprint + Aug 18 13:05:34 i suppose we start with cfbolz, aleale,arigo,hpk,pedronis on the activity reports + Aug 18 13:05:42 PREV: compliance test + Aug 18 13:05:42 Next: Sprint (more compliance tests) + Aug 18 13:05:42 blockers: - + Aug 18 13:05:55 LAST: plugged gc into the llinterp, preparation for an exam + exam + Aug 18 13:05:55 NEXT: working on gc, heidelberg + Aug 18 13:05:55 BLOCKERS: none + Aug 18 13:06:16 LAST: non-pypy work, codespeak.net migration/related infrastructure + Aug 18 13:06:16 NEXT: preparing and doing the heidelberg sprint + Aug 18 13:06:16 BLOCKERS: None + Aug 18 13:06:23 Last week: Vacation. + Aug 18 13:06:23 Next week: Catching up. + Aug 18 13:06:24 Blockers: No known. + Aug 18 13:06:44 DONE: progress on threads with a GIL; translating it + Aug 18 13:06:52 NEXT: more work on the same (nasty rare bugs around) + Aug 18 13:06:53 BLOCKER: no network access from my laptop :-( + Aug 18 13:07:06 Last: took some time off, worked a bit on translate_pypy.py itself, helped people + Aug 18 13:07:07 witth annotation problems, compiled Boehm for my machines + Aug 18 13:07:09 Next: (rtyping addresses) sprint + Aug 18 13:07:11 Issues: - + Aug 18 13:07:45 ok, i didn't get notice from logilab or christian + Aug 18 13:08:06 then i suppose we go on with heidelberg sprint planning + Aug 18 13:08:22 just as a background i am listing the issues from the announcements + Aug 18 13:08:32 - translation efforts: it's not completely clear + Aug 18 13:08:32 now what related task will be left at that time + Aug 18 13:08:32 - work on 2.4.1 compliancy: there are some failing compliancy + Aug 18 13:08:32 tests on which we plan to work + Aug 18 13:08:32 - rewriting c-extension modules/integrating existing rewrites + Aug 18 13:08:32 - all kinds of small release issues + Aug 18 13:08:32 - possibly some more LLVM efforts + Aug 18 13:09:03 i suppose we should go through them and try to get a status and plans for the sprints + Aug 18 13:09:05 does that make sense? + Aug 18 13:09:23 yes + Aug 18 13:09:34 nod + Aug 18 13:10:06 arigo, pedronis, cfbolz: or do you want to do it differently? + Aug 18 13:10:21 I am fine with that + Aug 18 13:10:28 me too + Aug 18 13:10:38 me too + Aug 18 13:10:46 ok, so translation tasks: what is left? let's start with threading because that is probably the most open field + Aug 18 13:11:05 arigo: could you say a few words on that? + Aug 18 13:11:15 it's kind of done + Aug 18 13:11:20 :-) + Aug 18 13:11:23 :-) + Aug 18 13:11:28 it's kind of impressive + Aug 18 13:11:43 but there are some bugs left somewhere (I get a test failure randomly from time to time) + Aug 18 13:11:55 and you used a GIL approach + Aug 18 13:12:04 in a modular way? + Aug 18 13:12:08 yes + Aug 18 13:12:20 the GIL code is in a single submodule + Aug 18 13:12:55 well from there I'd just like to point to a few files + Aug 18 13:13:09 right. + Aug 18 13:13:10 does it make sense to even try go for a different thread model during/until the sprint? + Aug 18 13:13:43 I don't know, maybe during the sprint we can discuss another simple locking policy + Aug 18 13:14:28 I also extended the annotator/rtyper to have "external types" in addition to external functions + Aug 18 13:14:34 I needed it for lock objects + Aug 18 13:15:04 sounds good to me, everyone else ok with the basic "we see if we want a second approach" or should we put more focus on getting more on threading? + Aug 18 13:15:43 we could decide that based on whether someone is very interested working on this + Aug 18 13:15:43 Sounds good to me. + Aug 18 13:15:45 I agree + Aug 18 13:16:35 pedronis: you too if i may ask? + Aug 18 13:16:55 I think we discuss this at the sprint + Aug 18 13:17:15 ok, but then on the first day i guess and in relation to the other tasks + Aug 18 13:17:30 i believe we can easily agree that we need an ongoing track on fixing and discussing compliancy + Aug 18 13:17:43 (but feel free to object) + Aug 18 13:17:54 and then there is the topic of preparing the release + Aug 18 13:18:07 i'd like to work the "little" issues out early on during the sprint + Aug 18 13:18:15 to not get into too much of a rush in the end + Aug 18 13:18:17 and isolating refcounting + Aug 18 13:18:25 + cfbolz GC work + Aug 18 13:18:40 although that is not really a release issue + Aug 18 13:18:52 the isolating refcount is + Aug 18 13:19:07 the fact that you still have GC work is related to the sprint, not the release + Aug 18 13:19:16 yes of course + Aug 18 13:19:20 yes, i think it makes sense to start off with that as well + Aug 18 13:19:38 I agree + Aug 18 13:19:40 so we have a compliancy and a GC track and maybe two people thinking a bit about the release + Aug 18 13:20:01 then what about llvm? + Aug 18 13:20:21 the llvm people are not here :-( + Aug 18 13:20:26 we obviously don't have richard and eric here but they are going to be at the sprint + Aug 18 13:20:33 does someone know the status? + Aug 18 13:20:41 they compiled PyPy yesterday + Aug 18 13:20:49 some external functions are still missing + Aug 18 13:21:04 I think Richard and Eric will want to work on it + Aug 18 13:21:07 yes, their pypy-dev mail hints that they'd like to continue to work on it + Aug 18 13:21:14 yes, makes sense i think + Aug 18 13:21:32 Richard said that he would like to think about consolidating the backends a bit + Aug 18 13:21:34 then we will probably also have parsing/compiling issues? + Aug 18 13:21:40 (i am a bit out of loop, can anyone help?) + Aug 18 13:21:57 yes, also a quite a bit of compliance failures are related to compile + Aug 18 13:22:29 from different error messages, to __future__ not working and such subtle issues + Aug 18 13:22:29 hpk: I think that the ST->AST transformer is done and they are RPythonifying it + Aug 18 13:23:02 ok, that will be an ongoing topic as well then i guess + Aug 18 13:23:17 so there are two fronts here, fixing bugs and progressing on moving the compiler to interp-level + Aug 18 13:23:19 actually i'd like pedronis or arigo to prepare the "heidelberg-planning" document for monday morning a bit + Aug 18 13:23:31 we can suggest a focus on the 1st front for the next sprint + Aug 18 13:23:38 how about _weakref? + Aug 18 13:24:00 aleale: could be related to my GC stuff, but I think it is too advanced + Aug 18 13:24:47 do we agree to ignore weakrefs for now? + Aug 18 13:25:04 sure + Aug 18 13:25:13 very good + Aug 18 13:25:25 * cfbolz notes that we have 5 min left + Aug 18 13:25:29 i think it's ok to ignore it + Aug 18 13:25:29 I mean with respect to what we promized to the EU + Aug 18 13:25:41 ok + Aug 18 13:25:57 yes, we should sit together monday evening or so and go through the eu deliverables again + Aug 18 13:26:03 in a physical sit-together + Aug 18 13:26:07 I think apart errno we have most of the core builtin modules + Aug 18 13:26:21 and errno shoulnd't be too hard modulo platform problems + Aug 18 13:26:43 (and i still hold that working on all platforms is not a EU-related goal) + Aug 18 13:26:49 yes, for now we can hard-code the errno constants from the underlying CPython's constants + Aug 18 13:26:52 we should think about documentation and documents also + Aug 18 13:27:09 right, that's the release focus for one, the eu-related docuemnts are still a different issue + Aug 18 13:27:13 * hpk notes three minutes left + Aug 18 13:27:15 right + Aug 18 13:27:36 arigo, pedronis: may i repeat my question if one of you could make a list of basic issues and put them into heidelberg-planning.txt ? + Aug 18 13:27:42 (using this session as an input) + Aug 18 13:27:57 it's good to have a starting base and then go through it at the sprint + Aug 18 13:27:59 pedronis: can I pong this to you? + Aug 18 13:28:07 it's going to be a busy week-end for me + Aug 18 13:28:22 hpk: bea sent a mail that the PO made some noises about "EU-packaged" deliverables + Aug 18 13:28:36 hpk: I can write a basic list + Aug 18 13:28:36 can we discuss this off-this-channel? + Aug 18 13:28:42 hpk: yes + Aug 18 13:28:43 pedronis: great, i can helpw ith it + Aug 18 13:29:00 ok, then we have an idea (which will evolve during the sprint anyway) + Aug 18 13:29:13 thanks + Aug 18 13:29:18 so i guess we should close the meeting for now and look forward for meeting in three days and have a beer together! + Aug 18 13:29:24 :-) + Aug 18 13:29:34 see you + Aug 18 13:29:53 see you + Aug 18 13:29:55 see you + Aug 18 13:29:56 bye From arigo at codespeak.net Sat Aug 20 14:28:06 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 20 Aug 2005 14:28:06 +0200 (CEST) Subject: [pypy-svn] r16183 - pypy/dist/pypy/objspace/std Message-ID: <20050820122806.B286827B50@code1.codespeak.net> Author: arigo Date: Sat Aug 20 14:28:04 2005 New Revision: 16183 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py Log: Can't use str() on unicode chars, nor comparison between non-unicode and unicode characters. Fix for unicode characters \u0100 and \U000010000. Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Sat Aug 20 14:28:04 2005 @@ -904,11 +904,6 @@ result[1] = quote i = 2 for ch in chars: - if ch == u'\\' or ch == str(quote) : - result[i] = '\\' - result[i + 1] = str(ch) - i += 2 - continue ## if ch == u"'": ## quote ='''"''' ## result[1] = quote @@ -917,7 +912,7 @@ ## i += 1 ## continue code = ord(ch) - if code > 0x10000: + if code >= 0x10000: # Resize if needed if i + 12 > len(result): result.extend(['\0'] * 100) @@ -933,7 +928,7 @@ result[i + 9] = hexdigits[(code >> 0) & 0xf] i += 10 continue - if code > 0x100: + if code >= 0x100: result[i] = '\\' result[i + 1] = "u" result[i + 2] = hexdigits[(code >> 12) & 0xf] @@ -942,6 +937,11 @@ result[i + 5] = hexdigits[(code >> 0) & 0xf] i += 6 continue + if code == ord('\\') or code == ord(quote): + result[i] = '\\' + result[i + 1] = chr(code) + i += 2 + continue if code == ord('\t'): result[i] = '\\' result[i + 1] = "t" From adim at codespeak.net Mon Aug 22 11:05:07 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Mon, 22 Aug 2005 11:05:07 +0200 (CEST) Subject: [pypy-svn] r16185 - in pypy/dist/pypy/interpreter: astcompiler pyparser Message-ID: <20050822090507.E614227B3F@code1.codespeak.net> Author: adim Date: Mon Aug 22 11:05:05 2005 New Revision: 16185 Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py Log: - Created three specific class for string consts, number consts, and None consts instead of using the original "Const" one This improves the SomeObjectness situation. (when using 'rpython_parse_fpdef' instead of 'working_parse_fpdef', only 3 calls remain SomeObject-ed) - Updated astcompiler.pycodegen to be able to process these new classes. - added small hack to test equality between SpecializedConst and original Const nodes (to make test pass) Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Mon Aug 22 11:05:05 2005 @@ -818,6 +818,15 @@ def visitConst(self, node): self.emit('LOAD_CONST', node.value) + def visitNoneConst(self, node): + self.emit('LOAD_CONST', None) + + def visitNumberConst(self, node): + self.emit('LOAD_CONST', node.number_value) + + def visitStringConst(self, node): + self.emit('LOAD_CONST', node.string_value) + def visitKeyword(self, node): self.emit('LOAD_CONST', node.name) self.visit(node.expr) Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Aug 22 11:05:05 2005 @@ -189,8 +189,8 @@ assert len(stack) == 1, "At the end of parse_fpdef, len(stack) should be 1, got %s" % stack return tokens_read, tuple(stack[0]) -parse_fpdef = rpython_parse_fpdef -# parse_fpdef = working_parse_fpdef +# parse_fpdef = rpython_parse_fpdef +parse_fpdef = working_parse_fpdef def parse_arglist(tokens): """returns names, defaults, flags""" @@ -351,12 +351,12 @@ first_child = stmt.nodes[0] if isinstance(first_child, ast.Discard): expr = first_child.expr - if isinstance(expr, ast.Const): + if isinstance(expr, StringConst): # This *is* a docstring, remove it from stmt list del stmt.nodes[0] - doc = expr.value + doc = expr.string_value return doc - + def to_lvalue(ast_node, flags): if isinstance( ast_node, ast.Name ): @@ -566,15 +566,16 @@ elif top.name == tok.NAME: builder.push( ast.Name(top.get_value()) ) elif top.name == tok.NUMBER: - builder.push( ast.Const(eval_number(top.get_value())) ) + # builder.push( ast.Const(eval_number(top.get_value())) ) + builder.push(NumberConst(eval_number(top.get_value()))) elif top.name == tok.STRING: # need to concatenate strings in atoms s = '' for token in atoms: assert isinstance(token, TokenObject) s += eval_string(token.get_value()) - builder.push( ast.Const(s) ) - # assert False, "TODO (String)" + # builder.push( ast.Const(s) ) + builder.push(StringConst(s)) elif top.name == tok.BACKQUOTE: builder.push(ast.Backquote(atoms[1])) else: @@ -780,7 +781,8 @@ for n in range(0,l,2): node = atoms[n] if isinstance(node, TokenObject) and node.name == tok.NEWLINE: - nodes.append(ast.Discard(ast.Const(None))) + # nodes.append(ast.Discard(ast.Const(None))) + nodes.append(ast.Discard(NoneConst())) else: nodes.append(node) builder.push(ast.Stmt(nodes)) @@ -790,7 +792,8 @@ if len(atoms) > 2: assert False, "return several stmts not implemented" elif len(atoms) == 1: - builder.push(ast.Return(ast.Const(None), None)) # XXX lineno + # builder.push(ast.Return(ast.Const(None), None)) # XXX lineno + builder.push(ast.Return(NoneConst(), None)) # XXX lineno else: builder.push(ast.Return(atoms[1], None)) # XXX lineno @@ -921,7 +924,8 @@ sliceobj_infos = [] for value in sliceinfos: if value is None: - sliceobj_infos.append(ast.Const(None)) + # sliceobj_infos.append(ast.Const(None)) + sliceobj_infos.append(NoneConst()) else: sliceobj_infos.append(value) builder.push(SlicelistObject('sliceobj', sliceobj_infos, None)) @@ -1390,6 +1394,54 @@ } ## Stack elements definitions ################################### +class StringConst(ast.Const): + """specicifc Const node for strings""" + def __init__(self, value, lineno=None): + self.lineno = lineno + # don't use "value" for attribute's name to avoid confusing + # the annotator + self.string_value = value + + def __repr__(self): + return "Const(%s)" % (repr(self.string_value),) + + def __eq__(self, other): + # XXX yurk : to make test pass + if other.__class__.__name__ == 'Const' and \ + other.value == self.string_value: + return True + return False + +class NumberConst(ast.Const): + """specific Const node for numbers""" + def __init__(self, value, lineno=None): + self.lineno = lineno + # don't use "value" for attribute's name to avoid confusing + # the annotator + self.number_value = value + + def __repr__(self): + return "Const(%s)" % (repr(self.number_value),) + + def __eq__(self, other): + if other.__class__.__name__ == 'Const' and \ + other.value == self.number_value: + return True + return False + +class NoneConst(ast.Const): + """specific Const node for None (probably not really needed)""" + def __init__(self, lineno=None): + self.lineno = lineno + self.value = None + + def __eq__(self, other): + if other.__class__.__name__ == 'Const' and \ + other.value is None: + return True + return False + + class RuleObject(ast.Node): """A simple object used to wrap a rule or token""" def __init__(self, name, count, src ): @@ -1539,7 +1591,7 @@ return self.rule_stack.pop(-1) def push(self, obj): - self.rule_stack.append( obj ) + self.rule_stack.append(obj) if not isinstance(obj, RuleObject) and not isinstance(obj, TokenObject): ## if DEBUG_MODE: ## print "Pushed:", str(obj), len(self.rule_stack) From arigo at codespeak.net Mon Aug 22 12:16:36 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Aug 2005 12:16:36 +0200 (CEST) Subject: [pypy-svn] r16186 - pypy/extradoc/sprintinfo Message-ID: <20050822101636.4A25E27B3E@code1.codespeak.net> Author: arigo Date: Mon Aug 22 12:16:35 2005 New Revision: 16186 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: Initial planning Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Mon Aug 22 12:16:35 2005 @@ -1,33 +1,83 @@ - PyPy Heidelberg sprint planning (22th-29st August) ----------------------------------------------------- +Armin Rigo +Samuele Pedroni +Carl Friedrich Bolz +Niklaus Haldimann +Holger Krekel +Richard Emslie +Jacob Hallen +Laura Creighton +Ludovic Aubry +Anders Chrigstroem +Christian Tismer +Anders Lehmann +Beatrice Duering +Eric van Riet Paap + +Rough Week planning:: + each day: 10 AM - 7 PM (lunch break at ~1-3pm) + + monday 22nd sprinting + tuesday 23rd sprinting + wednesday 24th sprinting + + thursday 25th break day! + + friday 26th sprinting / release + saturday 27th sprinting + sunday 28th sprinting / technical summary/some future planning + monday 29th sprinting/eu-meeting/cleanup + +* Release (PyPy-0.7) (hpk, .) + + - Documentation work + - Other: README, announcement, licenses & contributors... + - Release cutting & testing (important!) + - *try to be ready to cut on Friday morning!* + * Translation - - Finish(?) GIL-based threading + - Finish GIL-based threading: backend support, fix bugs? (arigo, rxe) - (Decide whether to try to implement other threading locking policies) + (probably not at the moment, let's see) - - Isolate refcounting in genc, and + - Isolate refcounting in genc, and (cfbolz, pedronis) have an option to enable and use Boehm instead -* 2.4.1 Compliance +* 2.4.1 Compliance (arre, tismer) + - Recategorize the tests in core/non-core ( = language compliancy) + - test_unicode, test_codecs (ale, jacob) - Fix/adjust/prioritize compliance test problems - - Do we want to try to pass test_unicode(/test_codecs) ? - Some other "non-core" tests revealing real bugs/problems? * Compiler/Parser - Fix bugs, missing features (some cause compliance regressions) - Work on making the compiler interp-level + st->ast mostly done, should go into the release (ludal, nik) + ast->bytecode is not going to be done for the release + (kept at app-level) + + - compiling unicode strings (see failing test_builtins) + https://codespeak.net/issue/pypy-dev/issue97 + - interactive mode parsing (issue115 -- use "single" instead of "exec"?) + high priority: why is "from __future__" not working? (flag missing?) + inputs that are a single string are considered docstrings + (also single unicode strings are considered docstrings) * Built-in modules - Do we still miss important os.* functionality? - - errno - - Enable our own array/_sre when translating + - errno (easy for now) + - Enable our own array/_sre when translating (try with the current + _sre and its interp-level parts, otherwise just use the app-level + one) - (Review builtin modules again to see if we missed something) + - 'math' must be finished (math.log()) * Fix/garden issues for the release in the tracker @@ -35,13 +85,6 @@ for the release - Review Hildes_to_Heidel.txt contents too -* Release - - - Documentation work - - Other: README, announcement, licenses & contributors... - - Release cutting & testing (important!) - - *try to be ready to cut on Friday morning!* - * LLVM backend - Improvement work to stabilize and match genc From arigo at codespeak.net Mon Aug 22 12:18:05 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Aug 2005 12:18:05 +0200 (CEST) Subject: [pypy-svn] r16187 - pypy/extradoc/sprintinfo Message-ID: <20050822101805.724AF27B42@code1.codespeak.net> Author: arigo Date: Mon Aug 22 12:18:04 2005 New Revision: 16187 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: Update from Ludovic. Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Mon Aug 22 12:18:04 2005 @@ -64,7 +64,8 @@ - compiling unicode strings (see failing test_builtins) https://codespeak.net/issue/pypy-dev/issue97 - - interactive mode parsing (issue115 -- use "single" instead of "exec"?) + - interactive mode parsing (issue115 -- use "single" instead of "exec"? + look at code.py from lib-python/2.4.1/) high priority: why is "from __future__" not working? (flag missing?) inputs that are a single string are considered docstrings (also single unicode strings are considered docstrings) From arigo at codespeak.net Mon Aug 22 12:23:53 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Aug 2005 12:23:53 +0200 (CEST) Subject: [pypy-svn] r16188 - in pypy/dist/pypy: module/thread/rpython module/thread/rpython/test rpython rpython/module Message-ID: <20050822102353.7137A27B41@code1.codespeak.net> Author: arigo Date: Mon Aug 22 12:23:49 2005 New Revision: 16188 Modified: pypy/dist/pypy/module/thread/rpython/exttable.py pypy/dist/pypy/module/thread/rpython/ll_thread.py pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py pypy/dist/pypy/rpython/annlowlevel.py pypy/dist/pypy/rpython/exceptiondata.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/lltype.py pypy/dist/pypy/rpython/module/support.py pypy/dist/pypy/rpython/rexternalobj.py pypy/dist/pypy/rpython/rspecialcase.py Log: Reorganized the low-level representation of "external types" to take advantage of the memory management that GcStruct provides. Now an object like a thread.lock is implemented as a GcStruct with a single field "obj" that is an inlined Opaque object. * updated lltype.py to allow Opaque objects to be inlined in structures. * allow thread.rpython.exttable to register a new standard exception, thread.error, raised by the release() method of locks. * thread.rpython.ll_thread: each function is divided in two functions, one that does the mallocing of the GcStruct for locks, or that reads the "obj" field of the GcStruct, and another that is the suggested_primitive, operating on the opaque object. Modified: pypy/dist/pypy/module/thread/rpython/exttable.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/exttable.py (original) +++ pypy/dist/pypy/module/thread/rpython/exttable.py Mon Aug 22 12:23:49 2005 @@ -3,18 +3,18 @@ """ import thread -from pypy.rpython.extfunctable import declare, declaretype +from pypy.rpython.extfunctable import declare, declaretype, standardexceptions module = 'pypy.module.thread.rpython.ll_thread' # ____________________________________________________________ # The external type thread.LockType -declaretype(thread.LockType, - "ThreadLock", - acquire = (bool, '%s/acquire_lock' % module), - release = (type(None), '%s/release_lock' % module), - ) +locktypeinfo = declaretype(thread.LockType, + "ThreadLock", + acquire = (bool, '%s/acquire_lock' % module), + release = (type(None), '%s/release_lock' % module), + ) # ____________________________________________________________ # Built-in functions needed in the rtyper @@ -22,3 +22,9 @@ declare(thread.start_new_thread, int, '%s/start_new_thread' % module) declare(thread.get_ident, int, '%s/get_ident' % module) declare(thread.allocate_lock, thread.LockType, '%s/allocate_lock' % module) + +# ____________________________________________________________ +# thread.error can be raised by the above + +# XXX a bit hackish +standardexceptions[thread.error] = True Modified: pypy/dist/pypy/module/thread/rpython/ll_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/ll_thread.py (original) +++ pypy/dist/pypy/module/thread/rpython/ll_thread.py Mon Aug 22 12:23:49 2005 @@ -4,7 +4,12 @@ """ import thread -from pypy.rpython.module.support import from_rexternalobj, to_rexternalobj +from pypy.rpython.lltype import malloc +from pypy.rpython.module.support import init_opaque_object, from_opaque_object +from pypy.module.thread.rpython.exttable import locktypeinfo + +LOCKCONTAINERTYPE = locktypeinfo.get_lltype() + def ll_thread_start_new_thread(funcptr, argtuple): # wrapper around ll_thread_start, to extract the single argument @@ -21,17 +26,27 @@ ll_thread_get_ident.suggested_primitive = True -def ll_thread_allocate_lock(): - lock = thread.allocate_lock() - return to_rexternalobj(lock) -ll_thread_allocate_lock.suggested_primitive = True +def newlock(opaqueptr): + init_opaque_object(opaqueptr, thread.allocate_lock()) +newlock.suggested_primitive = True -def ll_thread_acquire_lock(lockptr, waitflag): - lock = from_rexternalobj(lockptr) +def acquirelock(opaqueptr, waitflag): + lock = from_opaque_object(opaqueptr) return lock.acquire(waitflag) -ll_thread_acquire_lock.suggested_primitive = True +acquirelock.suggested_primitive = True -def ll_thread_release_lock(lockptr): - lock = from_rexternalobj(lockptr) +def releaselock(opaqueptr): + lock = from_opaque_object(opaqueptr) lock.release() -ll_thread_release_lock.suggested_primitive = True +releaselock.suggested_primitive = True + +def ll_thread_allocate_lock(): + lockcontainer = malloc(LOCKCONTAINERTYPE) + newlock(lockcontainer.obj) + return lockcontainer + +def ll_thread_acquire_lock(lockcontainer, waitflag): + return acquirelock(lockcontainer.obj, waitflag) + +def ll_thread_release_lock(lockcontainer): + releaselock(lockcontainer.obj) Modified: pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py (original) +++ pypy/dist/pypy/module/thread/rpython/test/test_ll_thread.py Mon Aug 22 12:23:49 2005 @@ -23,3 +23,15 @@ return ok1 and not ok2 and ok3 res = interpret(fn, []) assert res is True + +def test_thread_error(): + def fn(): + l = thread.allocate_lock() + try: + l.release() + except thread.error: + return True + else: + return False + res = interpret(fn, []) + assert res is True Modified: pypy/dist/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/dist/pypy/rpython/annlowlevel.py (original) +++ pypy/dist/pypy/rpython/annlowlevel.py Mon Aug 22 12:23:49 2005 @@ -56,17 +56,18 @@ key.append(s_obj.__class__) return tuple(key), bookkeeper.build_args('simple_call', new_args_s) - def override__to_rexternalobj(pol, s_obj): - assert isinstance(s_obj, annmodel.SomeExternalObject) - exttypeinfo = extfunctable.typetable[s_obj.knowntype] - OPAQUE = exttypeinfo.get_opaque_lltype() - return annmodel.SomePtr(lltype.Ptr(OPAQUE)) + def override__init_opaque_object(pol, s_opaqueptr, s_value): + assert isinstance(s_opaqueptr, annmodel.SomePtr) + assert isinstance(s_opaqueptr.ll_ptrtype.TO, lltype.OpaqueType) + assert isinstance(s_value, annmodel.SomeExternalObject) + exttypeinfo = extfunctable.typetable[s_value.knowntype] + assert s_opaqueptr.ll_ptrtype.TO._exttypeinfo == exttypeinfo + return annmodel.SomeExternalObject(exttypeinfo.typ) - def override__from_rexternalobj(pol, s_objptr): - assert isinstance(s_objptr, annmodel.SomePtr) - OPAQUE = s_objptr.ll_ptrtype.TO - assert isinstance(OPAQUE, lltype.OpaqueType) - exttypeinfo = OPAQUE.exttypeinfo + def override__from_opaque_object(pol, s_opaqueptr): + assert isinstance(s_opaqueptr, annmodel.SomePtr) + assert isinstance(s_opaqueptr.ll_ptrtype.TO, lltype.OpaqueType) + exttypeinfo = s_opaqueptr.ll_ptrtype.TO._exttypeinfo return annmodel.SomeExternalObject(exttypeinfo.typ) Modified: pypy/dist/pypy/rpython/exceptiondata.py ============================================================================== --- pypy/dist/pypy/rpython/exceptiondata.py (original) +++ pypy/dist/pypy/rpython/exceptiondata.py Mon Aug 22 12:23:49 2005 @@ -3,15 +3,12 @@ from pypy.rpython.annlowlevel import annotate_lowlevel_helper from pypy.rpython.lltype import Array, malloc, Ptr, PyObject, pyobjectptr from pypy.rpython.lltype import FuncType, functionptr, Signed +from pypy.rpython.extfunctable import standardexceptions class ExceptionData: """Public information for the code generators to help with exceptions.""" - # the exceptions that can be implicitely raised by some operations - standardexceptions = [TypeError, OverflowError, ValueError, - ZeroDivisionError, MemoryError, IOError] - def __init__(self, rtyper): self.make_standard_exceptions(rtyper) # (NB. rclass identifies 'Exception' and 'object') @@ -35,7 +32,7 @@ def make_standard_exceptions(self, rtyper): bk = rtyper.annotator.bookkeeper - for cls in self.standardexceptions: + for cls in standardexceptions: classdef = bk.getclassdef(cls) rclass.getclassrepr(rtyper, classdef).setup() @@ -72,7 +69,14 @@ if (clsdef and clsdef.cls is not Exception and issubclass(clsdef.cls, Exception)): cls = clsdef.cls - if cls.__module__ == 'exceptions' and not clsdef.attrs: + if cls in standardexceptions: + is_standard = True + assert not clsdef.attrs, ( + "%r should not have grown atributes" % (cls,)) + else: + is_standard = (cls.__module__ == 'exceptions' + and not clsdef.attrs) + if is_standard: r_inst = rclass.getinstancerepr(rtyper, clsdef) r_inst.setup() example = malloc(r_inst.lowleveltype.TO, immortal=True) Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Mon Aug 22 12:23:49 2005 @@ -31,7 +31,7 @@ def __init__(self, typ, tag, methods): self.typ = typ self.tag = tag - self.TYPE = None + self._TYPE = None self.methods = methods # {'name': ExtFuncInfo()} def get_annotation(self, methodname): @@ -46,13 +46,14 @@ if extfuncinfo.func is not None: yield (extfuncinfo.func, extfuncinfo) - def get_opaque_lltype(self): - if self.TYPE is None: + def get_lltype(self): + if self._TYPE is None: from pypy.rpython import lltype OPAQUE = lltype.OpaqueType(self.tag) - OPAQUE.exttypeinfo = self - self.TYPE = OPAQUE - return self.TYPE + OPAQUE._exttypeinfo = self + STRUCT = lltype.GcStruct(self.tag, ('obj', OPAQUE)) + self._TYPE = STRUCT + return self._TYPE class ImportMe: @@ -185,3 +186,14 @@ declare(rarithmetic.parts_to_float, float, 'll_strtod/parts_to_float') # float->string helper declare(rarithmetic.formatd, str, 'll_strtod/formatd') + +# ___________________________________________________________ +# the exceptions that can be implicitely raised by some operations +standardexceptions = { + TypeError : True, + OverflowError : True, + ValueError : True, + ZeroDivisionError: True, + MemoryError : True, + IOError : True, + } Modified: pypy/dist/pypy/rpython/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltype.py (original) +++ pypy/dist/pypy/rpython/lltype.py Mon Aug 22 12:23:49 2005 @@ -275,6 +275,15 @@ def __str__(self): return "%s (opaque)" % self.tag + def _inline_is_varsize(self, last): + return False # OpaqueType can be inlined + + def _container_example(self): + return _opaque(self) + + def _defl(self, parent=None, parentindex=None): + return self._container_example() + RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo") class PyObjectType(ContainerType): Modified: pypy/dist/pypy/rpython/module/support.py ============================================================================== --- pypy/dist/pypy/rpython/module/support.py (original) +++ pypy/dist/pypy/rpython/module/support.py Mon Aug 22 12:23:49 2005 @@ -20,12 +20,12 @@ dstchars[i] = srcchars[i] i += 1 -def to_rexternalobj(obj): - exttypeinfo = extfunctable.typetable[type(obj)] - OPAQUE = exttypeinfo.get_opaque_lltype() - return lltype.opaqueptr(OPAQUE, name=None, externalobj=obj) -to_rexternalobj._annspecialcase_ = "override:to_rexternalobj" +def init_opaque_object(opaqueptr, value): + "NOT_RPYTHON" + opaqueptr._obj.externalobj = value +init_opaque_object._annspecialcase_ = "override:init_opaque_object" -def from_rexternalobj(objptr): - return objptr._obj.externalobj -from_rexternalobj._annspecialcase_ = "override:from_rexternalobj" +def from_opaque_object(opaqueptr): + "NOT_RPYTHON" + return opaqueptr._obj.externalobj +from_opaque_object._annspecialcase_ = "override:from_opaque_object" Modified: pypy/dist/pypy/rpython/rexternalobj.py ============================================================================== --- pypy/dist/pypy/rpython/rexternalobj.py (original) +++ pypy/dist/pypy/rpython/rexternalobj.py Mon Aug 22 12:23:49 2005 @@ -18,8 +18,8 @@ def __init__(self, knowntype): self.exttypeinfo = typetable[knowntype] - OPAQUE = self.exttypeinfo.get_opaque_lltype() - self.lowleveltype = lltype.Ptr(OPAQUE) + TYPE = self.exttypeinfo.get_lltype() + self.lowleveltype = lltype.Ptr(TYPE) # The set of methods supported depends on 'knowntype', so we # cannot have rtype_method_xxx() methods directly on the # ExternalObjRepr class. But we can store them in 'self' now. Modified: pypy/dist/pypy/rpython/rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/rspecialcase.py (original) +++ pypy/dist/pypy/rpython/rspecialcase.py Mon Aug 22 12:23:49 2005 @@ -33,5 +33,10 @@ v, = hop.inputargs(hop.args_r[0]) return v -rtype_override_to_rexternalobj = rtype_identity_function -rtype_override_from_rexternalobj = rtype_identity_function +def rtype_override_init_opaque_object(hop, clsdef): + return hop.genop('init_opaque_object_should_never_be_seen_by_the_backend', + [], resulttype=hop.r_result) + +def rtype_override_from_opaque_object(hop, clsdef): + return hop.genop('from_opaque_object_should_never_be_seen_by_the_backend', + [], resulttype=hop.r_result) From hpk at codespeak.net Mon Aug 22 12:27:40 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 12:27:40 +0200 (CEST) Subject: [pypy-svn] r16189 - pypy/extradoc/sprintinfo Message-ID: <20050822102740.F2D2D27B3E@code1.codespeak.net> Author: hpk Date: Mon Aug 22 12:27:39 2005 New Revision: 16189 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: fix ReST Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Mon Aug 22 12:27:39 2005 @@ -60,7 +60,7 @@ - Work on making the compiler interp-level st->ast mostly done, should go into the release (ludal, nik) ast->bytecode is not going to be done for the release - (kept at app-level) + (kept at app-level) - compiling unicode strings (see failing test_builtins) https://codespeak.net/issue/pypy-dev/issue97 From lac at codespeak.net Mon Aug 22 12:36:08 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Mon, 22 Aug 2005 12:36:08 +0200 (CEST) Subject: [pypy-svn] r16190 - pypy/dist/pypy/tool Message-ID: <20050822103608.6062827B41@code1.codespeak.net> Author: lac Date: Mon Aug 22 12:36:07 2005 New Revision: 16190 Added: pypy/dist/pypy/tool/getdocstrings.py (contents, props changed) Log: So I won't lose it again. :-( Added: pypy/dist/pypy/tool/getdocstrings.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/getdocstrings.py Mon Aug 22 12:36:07 2005 @@ -0,0 +1,119 @@ +import autopath +import re +from os import listdir + +where = autopath.pypydir + '/objspace/std/' +triplequotes = '(' + "'''" + '|' + '"""' + ')' +quote = '(' + "'" + '|' + '"' + ')' +doc = re.compile(r"__doc__\s+=\s+" + triplequotes + + r"(?P.*)"+ triplequotes , + re.DOTALL + ) + +def mk_std_filelist(): + ''' go to pypy/objs/std and get all the *type.py files ''' + filelist = [] + filenames = listdir(where) + for f in filenames: + if f.endswith('type.py'): + filelist.append(f) + return filelist + +def mk_typelist(filelist): + ''' generate a list of the types we expect to find in our files''' + return [f[:-7] for f in filelist] + +def compile_doc(): + return re.compile(r"__doc__\s+=\s+" + triplequotes + + r"(?P.*)"+ triplequotes , + re.DOTALL + ) + +def compile_typedef(match): + return re.compile(r"(?P\s*)" + + r"(?P" + match + + "_typedef = StdTypeDef+\s*\(\s*" + + quote + match + quote + ",)", + re.DOTALL + ) + +def compile_typedef_match(matchstring, sourcefile): + return re.compile(r"(?P\s+)" + + r"(?P" + matchstring + + "_typedef = StdTypeDef+\s*\(\s*" + + quote + matchstring + quote + ",)" + + r"(?P.*\s+)" + + r"(?P__new__)", + re.DOTALL + ).match(sourcefile).span() + +if __name__ == '__main__': + + filenames = listdir(where) + + docstrings = [] + + for f in filenames: + if f.endswith('type.py'): + match = f[:-7] + s = match + '.__doc__' + + try: + cpydoc = eval(match + '.__doc__') + #cpydoc = 'cpy_stuff' + except NameError: # No CPython docstring + cpydoc = None + + sourcefile = file(where + f).read() + + + # will produce erroneous result if you nest triple quotes + # in your docstring. + + doc = re.compile(r"__doc__\s+=\s+" + triplequotes + + r"(?P.*)"+ triplequotes , + re.DOTALL + ) + typedef = re.compile(r"(?P\s+)" + + r"(?P" + match + + "_typedef = StdTypeDef+\s*\(\s*" + + quote + match + quote + ",)" + + r"(?P.*\s+)" + + r"(?P__new__)", + re.DOTALL) + + try: + pypydoc = doc.search(sourcefile).group('docstring') + #pypydoc = 'pypy_stuff' + except AttributeError: # No pypy docstring + pypydoc = None + tdsearch = None + try: + tdsearch = typedef.search(sourcefile).group('typeassign') + newsearch = typedef.search(sourcefile).group('newassign') + if tdsearch: + print tdsearch, ' found', match + print newsearch + else: + print tdsearch, ' not found', match + + except AttributeError: + pass # so stringtype does not blow up. + + docstrings.append((match, cpydoc, pypydoc)) + + for (m, c, p) in docstrings: + if p: + print m, 'already has a pypydoc' + elif not c: + print m, 'does not have a cpydoc' + elif not tdsearch: + print m, 'has cpydoc but no ..._typedef = StdTypeDef. Skipping' + else: + print m, 'has cpydoc and ..._typedef = StdTypeDef. Inserting' + + + + + + From lac at codespeak.net Mon Aug 22 12:54:43 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Mon, 22 Aug 2005 12:54:43 +0200 (CEST) Subject: [pypy-svn] r16191 - pypy/dist/pypy/tool/test Message-ID: <20050822105443.8439F27B48@code1.codespeak.net> Author: lac Date: Mon Aug 22 12:54:42 2005 New Revision: 16191 Added: pypy/dist/pypy/tool/test/test_getdocstrings.py (contents, props changed) Log: Let's not lose this one either. Added: pypy/dist/pypy/tool/test/test_getdocstrings.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/test/test_getdocstrings.py Mon Aug 22 12:54:42 2005 @@ -0,0 +1,63 @@ +import autopath +from os import listdir +import py, re + +this_dir = autopath.this_dir +pypy_dir = autopath.pypydir +# Naming weirdness: why not both pypy_dir and this_dir or pypydir and thisdir + +from pypy.tool.getdocstrings import quote, triplequotes, doc +from pypy.tool.getdocstrings import mk_std_filelist, mk_typelist + +class TestDocStringInserter: + def setup_method(self, method): + self.fd1 = file(this_dir+'/fordocstrings1', 'r') + + def teardown_method(self, method): + self.fd1.close() + + def test_mkfilelist(self): + assert mk_std_filelist() == [ + 'basestringtype.py', 'unicodetype.py', 'inttype.py', + 'nonetype.py', 'longtype.py', 'slicetype.py', + 'itertype.py', 'floattype.py', 'typetype.py', + 'dicttype.py', 'dictproxytype.py', 'tupletype.py', + 'booltype.py', 'objecttype.py', 'stringtype.py', + 'listtype.py'] + + def test_typelist(self): + assert mk_typelist(mk_std_filelist()) == [ + 'basestring', 'unicode', 'int', 'none', 'long', + 'slice', 'iter', 'float', 'type', 'dict', + 'dictproxy', 'tuple', 'bool', 'object', 'string', + 'list'] + + def test_gottestfile(self): + s = self.fd1.read() # whole file as string + + s1 = 'from pypy.objspace.std.stdtypedef import *\n\n\n# ____________________________________________________________\n\nbasestring_typedef = StdTypeDef("basestring",\n )\n' + + assert s == s1 + + + def test_compile_typedef(self): + match = 'basestring' + s = self.fd1.read() + + typedef = re.compile(r"(?P\s*)" + + r"(?P" + match + + "_typedef = StdTypeDef+\s*\(\s*" + + quote + match + quote + ",)", + re.DOTALL + ) + + print s + tdsearch = typedef.search(s).group('typeassign') + + assert tdsearch + + + + + + From hpk at codespeak.net Mon Aug 22 13:11:01 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 13:11:01 +0200 (CEST) Subject: [pypy-svn] r16192 - pypy/dist/lib-python Message-ID: <20050822111101.384B627B47@code1.codespeak.net> Author: hpk Date: Mon Aug 22 13:11:00 2005 New Revision: 16192 Modified: pypy/dist/lib-python/conftest.py Log: be more careful about if os.path.samefile() exists for the warning of being in the wrong directory running tests. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Aug 22 13:11:00 2005 @@ -968,7 +968,9 @@ # Sanity check (could be done more nicely too) # import os -if os.path.samefile(os.getcwd(), str(regrtestdir.dirpath())): +samefile = getattr(os.path, 'samefile', + lambda x,y : str(x) == str(y)) +if samefile(os.getcwd(), str(regrtestdir.dirpath())): raise NotImplementedError( "Cannot run py.test with this current directory:\n" "the app-level sys.path will contain %s before %s)." % ( From pedronis at codespeak.net Mon Aug 22 13:13:58 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 22 Aug 2005 13:13:58 +0200 (CEST) Subject: [pypy-svn] r16193 - pypy/dist/pypy/rpython Message-ID: <20050822111358.6466027B47@code1.codespeak.net> Author: pedronis Date: Mon Aug 22 13:13:56 2005 New Revision: 16193 Modified: pypy/dist/pypy/rpython/exceptiondata.py Log: re-attach standardexceptions to ExceptionData as a class attribute Modified: pypy/dist/pypy/rpython/exceptiondata.py ============================================================================== --- pypy/dist/pypy/rpython/exceptiondata.py (original) +++ pypy/dist/pypy/rpython/exceptiondata.py Mon Aug 22 13:13:56 2005 @@ -8,6 +8,7 @@ class ExceptionData: """Public information for the code generators to help with exceptions.""" + standardexceptions = standardexceptions def __init__(self, rtyper): self.make_standard_exceptions(rtyper) @@ -32,7 +33,7 @@ def make_standard_exceptions(self, rtyper): bk = rtyper.annotator.bookkeeper - for cls in standardexceptions: + for cls in self.standardexceptions: classdef = bk.getclassdef(cls) rclass.getclassrepr(rtyper, classdef).setup() @@ -69,7 +70,7 @@ if (clsdef and clsdef.cls is not Exception and issubclass(clsdef.cls, Exception)): cls = clsdef.cls - if cls in standardexceptions: + if cls in self.standardexceptions: is_standard = True assert not clsdef.attrs, ( "%r should not have grown atributes" % (cls,)) From hpk at codespeak.net Mon Aug 22 13:55:45 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 13:55:45 +0200 (CEST) Subject: [pypy-svn] r16194 - pypy/dist/lib-python Message-ID: <20050822115545.10BFC27B47@code1.codespeak.net> Author: hpk Date: Mon Aug 22 13:55:43 2005 New Revision: 16194 Modified: pypy/dist/lib-python/conftest.py Log: be more accepting towards problems in getting the svn-revisions determined (mostly fails to either a missing svn binary or a wrong locale) Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Mon Aug 22 13:55:43 2005 @@ -786,8 +786,14 @@ def getrev(path): try: return py.path.svnwc(pypydir).info().rev - except py.process.cmdexec.Error: - return 'unknown' # on windows people not always have 'svn' in their path + except (KeyboardInterrupt, SystemExit): + raise + except: + # on windows people not always have 'svn' in their path + # but there are also other kinds of problems that + # could occur and we just default to revision + # "unknown" for them + return 'unknown' class RunFileExternal(py.test.collect.Module): def __init__(self, name, parent, regrtest): From ericvrp at codespeak.net Mon Aug 22 14:05:56 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 22 Aug 2005 14:05:56 +0200 (CEST) Subject: [pypy-svn] r16195 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050822120556.6152027B43@code1.codespeak.net> Author: ericvrp Date: Mon Aug 22 14:05:55 2005 New Revision: 16195 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/support.py Log: * adding tail tag to calls, since we are not using alloca at all at the moment. * cleaning up Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Mon Aug 22 14:05:55 2005 @@ -4,6 +4,9 @@ log = log.codewriter +DEFAULT_TAIL = 'tail' #or '' +DEFAULT_CCONV = 'fastcc' #or 'ccc' + class CodeWriter(object): def __init__(self, f, show_line_number=False): self.f = f @@ -46,7 +49,7 @@ self.append("%s = type %s (%s)" % (name, rettyperepr, ", ".join(argtypereprs))) - def declare(self, decl, cconv='fastcc'): + def declare(self, decl, cconv=DEFAULT_CCONV): self.append("declare %s %s" %(cconv, decl,)) def startimpl(self): @@ -68,7 +71,7 @@ self.indent("switch %s %s, label %%%s [%s ]" % (intty, cond, defaultdest, labels)) - def openfunc(self, decl, is_entrynode=False, cconv='fastcc'): + def openfunc(self, decl, is_entrynode=False, cconv=DEFAULT_CCONV): self.malloc_count = count(0).next self.newline() if is_entrynode: @@ -104,21 +107,30 @@ def shiftop(self, name, targetvar, type_, ref1, ref2): self.indent("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) - def call(self, targetvar, returntype, functionref, argrefs, argtypes, cconv='fastcc'): + #from: http://llvm.cs.uiuc.edu/docs/LangRef.html + #The optional "tail" marker indicates whether the callee function accesses any + # allocas or varargs in the caller. If the "tail" marker is present, the function + # call is eligible for tail call optimization. Note that calls may be marked + # "tail" even if they do not occur before a ret instruction. + def call(self, targetvar, returntype, functionref, argrefs, argtypes, tail=DEFAULT_TAIL, cconv=DEFAULT_CCONV): + if cconv is not 'fastcc': + tail = '' arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("%s = call %s %s %s(%s)" % (targetvar, cconv, returntype, functionref, + self.indent("%s = %s call %s %s %s(%s)" % (targetvar, tail, cconv, returntype, functionref, ", ".join(arglist))) - def call_void(self, functionref, argrefs, argtypes, cconv='fastcc'): + def call_void(self, functionref, argrefs, argtypes, tail=DEFAULT_TAIL, cconv=DEFAULT_CCONV): + if cconv is not 'fastcc': + tail = '' arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] - self.indent("call %s void %s(%s)" % (cconv, functionref, ", ".join(arglist))) + self.indent("%s call %s void %s(%s)" % (tail, cconv, functionref, ", ".join(arglist))) - def invoke(self, targetvar, returntype, functionref, argrefs, argtypes, label, except_label, cconv='fastcc'): + def invoke(self, targetvar, returntype, functionref, argrefs, argtypes, label, except_label, cconv=DEFAULT_CCONV): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] self.indent("%s = invoke %s %s %s(%s) to label %%%s except label %%%s" % (targetvar, cconv, returntype, functionref, ", ".join(arglist), label, except_label)) - def invoke_void(self, functionref, argrefs, argtypes, label, except_label, cconv='fastcc'): + def invoke_void(self, functionref, argrefs, argtypes, label, except_label, cconv=DEFAULT_CCONV): arglist = ["%s %s" % item for item in zip(argtypes, argrefs)] self.indent("invoke %s void %s(%s) to label %%%s except label %%%s" % (cconv, functionref, ", ".join(arglist), label, except_label)) @@ -126,7 +138,7 @@ self.indent("%(targetvar)s = cast %(fromtype)s " "%(fromvar)s to %(targettype)s" % locals()) - def malloc(self, targetvar, type_, size=1, atomic=False, cconv='fastcc'): + def malloc(self, targetvar, type_, size=1, atomic=False, cconv=DEFAULT_CCONV): n = self.malloc_count() if n: cnt = ".%d" % n Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Mon Aug 22 14:05:55 2005 @@ -12,19 +12,13 @@ gc_boehm = """declare ccc sbyte* %GC_malloc(uint) declare ccc sbyte* %GC_malloc_atomic(uint) -;XXX now trying to set only null terminator of varsize array for chars! -; might need to clear the hash value of rpystrings too. -declare ccc sbyte* %memset(sbyte*, int, uint) - internal fastcc sbyte* %gc_malloc(uint %n) { %ptr = call ccc sbyte* %GC_malloc(uint %n) - ;call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) ret sbyte* %ptr } internal fastcc sbyte* %gc_malloc_atomic(uint %n) { %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) - ;call ccc sbyte* %memset(sbyte* %ptr, int 0, uint %n) ret sbyte* %ptr } """ Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Mon Aug 22 14:05:55 2005 @@ -4,6 +4,7 @@ declare ccc int %puts(sbyte*) declare ccc int %strlen(sbyte*) declare ccc int %strcmp(sbyte*, sbyte*) +declare ccc sbyte* %memset(sbyte*, int, uint) %__print_debug_info = internal global bool false %__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" From pedronis at codespeak.net Mon Aug 22 14:10:12 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 22 Aug 2005 14:10:12 +0200 (CEST) Subject: [pypy-svn] r16196 - pypy/dist/pypy/translator/c Message-ID: <20050822121012.36B0027B43@code1.codespeak.net> Author: pedronis Date: Mon Aug 22 14:10:11 2005 New Revision: 16196 Modified: pypy/dist/pypy/translator/c/funcgen.py Log: moved around where we do incref for operation results, in preparation to factoring out and starting to genaralize how the gc strategy is hooked in genc code generation (cfbolz, pedronis) --This line, and those below, will be ignored-- M translator/c/funcgen.py Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Mon Aug 22 14:10:11 2005 @@ -184,9 +184,7 @@ del has_ref[a1] else: assert self.lltypemap(a1) == self.lltypemap(a2) - line = self.cincref(a2) - if line: - increfs.append(line) + increfs.append(a2) # warning, the order below is delicate to get right: # 1. decref the old variables that are not passed over for v in has_ref: @@ -197,8 +195,10 @@ for line in gen_assignments(assignments): yield line # 3. incref the new variables if needed - for line in increfs: - yield line + for a2 in increfs: + line = self.cincref(a2) + if line: + yield line yield 'goto block%d;' % blocknum[link.target] # collect all blocks @@ -228,6 +228,11 @@ yield '%s(%s);' % (macro, ', '.join(lst)) to_release.append(op.result) + if op.opname !='direct_call' and self.lltypemap(op.result) != PyObjPtr: # xxx factor out + line = self.cincref(op.result) + if line: + yield line + err_reachable = False if len(block.exits) == 0: if len(block.inputargs) == 2: # exc_cls, exc_value @@ -395,9 +400,10 @@ result = ['%s = %s;' % (newvalue, sourceexpr)] # need to adjust the refcount of the result - increfstmt = self.db.cincrefstmt(newvalue, T) - if increfstmt: - result.append(increfstmt) + if T == PyObjPtr: # xxx factor out + increfstmt = self.db.cincrefstmt(newvalue, T) + if increfstmt: + result.append(increfstmt) result = '\t'.join(result) if T == Void: result = '/* %s */' % result @@ -408,7 +414,7 @@ result = ['%s = %s;' % (targetexpr, newvalue)] # need to adjust some refcounts T = self.lltypemap(op.args[2]) - decrefstmt = self.db.cdecrefstmt('prev', T) + decrefstmt = self.db.cdecrefstmt('prev', T) # xxx factor out write barrier increfstmt = self.db.cincrefstmt(newvalue, T) if increfstmt: result.append(increfstmt) @@ -484,7 +490,7 @@ result = ['OP_ZERO_MALLOC(sizeof(%s), %s, %s);' % (cdecl(typename, ''), eresult, err), - '%s->%s = 1;' % (eresult, + '%s->%s = 0;' % (eresult, # xxx the incref is generically done on the results self.db.gettypedefnode(TYPE).refcount), ] return '\t'.join(result) @@ -513,7 +519,7 @@ err), '%s->%s = %s;' % (eresult, lenfld, elength), - '%s->%s = 1;' % (eresult, + '%s->%s = 0;' % (eresult, # xxx the incref is generically done on the results nodedef.refcount), ] return '\t'.join(result) @@ -525,20 +531,23 @@ result.append('%s = (%s)%s;' % (self.expr(op.result), cdecl(typename, ''), self.expr(op.args[0]))) - line = self.cincref(op.result) - if line: - result.append(line) + if TYPE == PyObjPtr: # xxx factor out + line = self.cincref(op.result) + if line: + result.append(line) return '\t'.join(result) def OP_SAME_AS(self, op, err): result = [] - assert self.lltypemap(op.args[0]) == self.lltypemap(op.result) - if self.lltypemap(op.result) != Void: + TYPE = self.lltypemap(op.result) + assert self.lltypemap(op.args[0]) == TYPE + if TYPE != Void: result.append('%s = %s;' % (self.expr(op.result), self.expr(op.args[0]))) - line = self.cincref(op.result) - if line: - result.append(line) + if TYPE == PyObjPtr: # xxx factor out + line = self.cincref(op.result) + if line: + result.append(line) return '\t'.join(result) def cincref(self, v): From ale at codespeak.net Mon Aug 22 14:11:17 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 22 Aug 2005 14:11:17 +0200 (CEST) Subject: [pypy-svn] r16197 - pypy/dist/pypy/module/_codecs Message-ID: <20050822121117.643A027B43@code1.codespeak.net> Author: ale Date: Mon Aug 22 14:11:16 2005 New Revision: 16197 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: Correcting errors Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Mon Aug 22 14:11:16 2005 @@ -90,7 +90,7 @@ lookup = codec_lookup -def encode(v, encoding='defaultencoding',errors='strict'): +def encode(v, encoding=None, errors='strict'): """encode(obj, [encoding[,errors]]) -> object Encodes obj using the codec registered for encoding. encoding defaults @@ -100,6 +100,8 @@ 'xmlcharrefreplace' as well as any other name registered with codecs.register_error that can handle ValueErrors. """ + if encoding == None: + encoding = sys.getdefaultencoding() if isinstance(encoding,str): encoder = lookup(encoding)[0] if encoder and isinstance(errors,str): @@ -110,7 +112,7 @@ else: raise TypeError("Encoding must be a string") -def decode(obj,encoding='defaultencoding',errors='strict'): +def decode(obj,encoding=None,errors='strict'): """decode(obj, [encoding[,errors]]) -> object Decodes obj using the codec registered for encoding. encoding defaults @@ -120,6 +122,8 @@ as well as any other name registerd with codecs.register_error that is able to handle ValueErrors. """ + if encoding == None: + encoding = sys.getdefaultencoding() if isinstance(encoding,str): decoder = lookup(encoding)[1] if decoder and isinstance(errors,str): @@ -274,13 +278,19 @@ res = u''.join(p) return res, len(res) -def utf_16_ex_decode( data,errors='strict',final = True): +def utf_16_ex_decode( data,errors='strict',byteorder=0,final = 0): """None """ - res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'native') + if byteorder == 0: + byteorder = 'native' + elif byteorder == -1: + byteorder = 'little' + else: + byteorder = 'big' + res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,byteorder) res = ''.join(res) - return res, len(res) -# XXX escape_decode Check if this is right + return res, len(res), byteorder + # XXX needs error messages when the input is invalid def escape_decode(data,errors='strict'): """None @@ -403,14 +413,14 @@ res = ''.join(res) return res, len(res) -def utf_16_le_decode( data,errors='strict',final = True): +def utf_16_le_decode( data,errors='strict',byteorder=0, final = 0): """None """ res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little') res = ''.join(res) return res, len(res) -def utf_16_be_decode( data,errors='strict',final = True): +def utf_16_be_decode( data,errors='strict',byteorder=0, final = 0): """None """ res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big') @@ -922,8 +932,8 @@ errmsg = "truncated data" startinpos = q endinpos = len(s) - unicode_call_errorhandler() -## /* The remaining input chars are ignored if the callback + unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) +# /* The remaining input chars are ignored if the callback ## chooses to skip the input */ ch = (ord(s[q+ihi]) << 8) | ord(s[q+ilo]) @@ -938,7 +948,7 @@ errmsg = "unexpected end of data" startinpos = q-2 endinpos = len(s) - unicode_call_errorhandler + unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) if (0xD800 <= ch and ch <= 0xDBFF): ch2 = (ord(s[q+ihi]) << 8) | ord(s[q+ilo]) @@ -957,12 +967,12 @@ errmsg = "illegal UTF-16 surrogate" startinpos = q-4 endinpos = startinpos+2 - unicode_call_errorhandler + unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) errmsg = "illegal encoding" startinpos = q-2 endinpos = startinpos+2 - unicode_call_errorhandler + unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) return p From adim at codespeak.net Mon Aug 22 14:54:04 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Mon, 22 Aug 2005 14:54:04 +0200 (CEST) Subject: [pypy-svn] r16198 - in pypy/dist/pypy/interpreter: astcompiler pyparser Message-ID: <20050822125404.2702227B43@code1.codespeak.net> Author: adim Date: Mon Aug 22 14:54:01 2005 New Revision: 16198 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py Log: renamed ast.Name's "name" attribute into "varname" to avoid annotation conflicts with other "name" attributes in ast.py. This removes 2 SomeObject-ness problems. Still 1 remaining ... Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Mon Aug 22 14:54:01 2005 @@ -1088,17 +1088,18 @@ class Name(Node): def __init__(self, name, lineno=None): - self.name = name + # self.name = name + self.varname = name self.lineno = lineno def getChildren(self): - return self.name, + return self.varname, def getChildNodes(self): return () def __repr__(self): - return "Name(%s)" % (repr(self.name),) + return "Name(%s)" % (repr(self.varname),) def accept(self, visitor, args): return visitor.visitName(self, args) Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Mon Aug 22 14:54:01 2005 @@ -837,7 +837,7 @@ def visitName(self, node): self.set_lineno(node) - self.loadName(node.name) + self.loadName(node.varname) def visitPass(self, node): self.set_lineno(node) Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Aug 22 14:54:01 2005 @@ -81,7 +81,7 @@ else: last_token = arguments.pop() assert isinstance(last_token, ast.Name) # used by rtyper - arguments.append(ast.Keyword(last_token.name, cur_token)) + arguments.append(ast.Keyword(last_token.varname, cur_token)) building_kw = False kw_built = True elif cur_token.name == tok.COMMA: @@ -360,14 +360,14 @@ def to_lvalue(ast_node, flags): if isinstance( ast_node, ast.Name ): - return ast.AssName( ast_node.name, flags ) + return ast.AssName(ast_node.varname, flags) + # return ast.AssName(ast_node.name, flags) elif isinstance(ast_node, ast.Tuple): nodes = [] # FIXME: should ast_node.getChildren() but it's not annotable # because of flatten() for node in ast_node.nodes: nodes.append(to_lvalue(node, flags)) - # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssTuple(nodes) elif isinstance(ast_node, ast.List): nodes = [] @@ -375,7 +375,6 @@ # because of flatten() for node in ast_node.nodes: nodes.append(to_lvalue(node, flags)) - # nodes.append(ast.AssName(node.name, consts.OP_ASSIGN)) return ast.AssList(nodes) elif isinstance(ast_node, ast.Getattr): expr = ast_node.expr From hpk at codespeak.net Mon Aug 22 15:20:56 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 15:20:56 +0200 (CEST) Subject: [pypy-svn] r16200 - pypy/extradoc/sprintinfo Message-ID: <20050822132056.CCD7827B47@code1.codespeak.net> Author: hpk Date: Mon Aug 22 15:20:55 2005 New Revision: 16200 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: detail out the release-tasks fix some more ReST Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Mon Aug 22 15:20:55 2005 @@ -30,14 +30,33 @@ sunday 28th sprinting / technical summary/some future planning monday 29th sprinting/eu-meeting/cleanup -* Release (PyPy-0.7) (hpk, .) +Release (PyPy-0.7) (hpk, .):: - - Documentation work - - Other: README, announcement, licenses & contributors... - - Release cutting & testing (important!) - - *try to be ready to cut on Friday morning!* + - Documentation work: + - update architecture "status of the implementation (May 2005)" + to reflect the 0.7 situation + - update getting_started.txt to reflect the 0.7 release + and include instruction on how to translate + - possibly streamline the tool chain + - do we have an easy-to-explain tool chain working for win32? + - maybe globally use "bytecode interpreter" instead of "plain interpreter" + - write 0.7.0 release announcement + README + - fix download locations, prepare/try out packaging + - regenerate contributors in LICENSE file + - revisit/refine LICENSE files + - put a LICENSE file in lib-python/ + - strip out a number of names (especially the ones that + have agreed to that on pypy-dev with the 0.6 release) + - RELEASE CUTTING friday morning: + - copy pypy/dist to pypy/release/0.7.x + and work on 0.7.x regarding remaining release issues + - which documentation should be served on the web + page? Probably just serving dist would fit for now. + Later in September we should look into splitting + "trunk" and release-documentation. + - do we introduce pypy/trunk finally? -* Translation +Translation - Finish GIL-based threading: backend support, fix bugs? (arigo, rxe) @@ -47,14 +66,14 @@ - Isolate refcounting in genc, and (cfbolz, pedronis) have an option to enable and use Boehm instead -* 2.4.1 Compliance (arre, tismer) +2.4.1 Compliance (arre, tismer) - Recategorize the tests in core/non-core ( = language compliancy) - test_unicode, test_codecs (ale, jacob) - Fix/adjust/prioritize compliance test problems - Some other "non-core" tests revealing real bugs/problems? -* Compiler/Parser +Compiler/Parser - Fix bugs, missing features (some cause compliance regressions) - Work on making the compiler interp-level @@ -80,29 +99,29 @@ - (Review builtin modules again to see if we missed something) - 'math' must be finished (math.log()) -* Fix/garden issues for the release in the tracker +Fix/garden issues for the release in the tracker - Go over the issues in the tracker: close, postpone or fix them as needed for the release - Review Hildes_to_Heidel.txt contents too -* LLVM backend +LLVM backend - Improvement work to stabilize and match genc - (Try to share code with genc?) -* GC +GC - Complete SoC GC framework (cfbolz) - (Start to think how/what is still missing to leverage it for Phase 2) - (related: isolating refcounting) -* Cleanups +Cleanups - We didn't really manage to tackle the cleanups listed in Hildes_to_Heidel.txt; do we want, have we the time to address some of them during the sprint for the release -* Future Planning +Future Planning - Plan work until next sprint - Consider priorities up to review From adim at codespeak.net Mon Aug 22 15:23:28 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Mon, 22 Aug 2005 15:23:28 +0200 (CEST) Subject: [pypy-svn] r16201 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050822132328.AA6E327B43@code1.codespeak.net> Author: adim Date: Mon Aug 22 15:23:26 2005 New Revision: 16201 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py Log: - use a common baseclass for RuleObject and TempRuleObject and use specific attributes for each of those classes (this removes the last SomeObject problem) - small cleans No more SomeObject-ness in astbuilder, but : - we're still using an incomplete implementation of eval_string() and eval_number() (we should use the other existing ones in PyPy) - astcompiler still has to be modified to be able to use the RPYTHON implementation of parse_fpdef(). Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Aug 22 15:23:26 2005 @@ -24,8 +24,6 @@ (token.get_value() == 'except' or token.get_value() == 'else'): break clause_length += 1 - # if clause_length >= len(tokens): - # raise Exception if clause_length == 3: # case 'except: body' return (3, None, None, tokens[2]) @@ -76,8 +74,6 @@ if not isinstance(cur_token, TokenObject): if not building_kw: arguments.append(cur_token) - # elif kw_built: - # raise SyntaxError("non-keyword arg after keyword arg (%s)" % (cur_token)) else: last_token = arguments.pop() assert isinstance(last_token, ast.Name) # used by rtyper @@ -202,8 +198,6 @@ while index < l: cur_token = tokens[index] index += 1 -## if isinstance(cur_token, FPListObject): -## names.append(cur_token.get_value()) if not isinstance(cur_token, TokenObject): # XXX: think of another way to write this test defaults.append(cur_token) @@ -403,7 +397,7 @@ i = nb while i>0: obj = builder.pop() - if isinstance(obj, RuleObject): + if isinstance(obj, BaseRuleObject): i += obj.count else: atoms.append( obj ) @@ -444,8 +438,6 @@ return '' # XXX: is it RPYTHON to do this value[index:-index] chars = [char for char in value[index:len(value)-index]] -## for index in range(index, len(value)-index): -## result += value[index] result = ''.join(chars) result = result.replace('\\\\', '\\') d = {'\\b' : '\b', '\\f' : '\f', '\\t' : '\t', '\\n' : '\n', @@ -565,7 +557,6 @@ elif top.name == tok.NAME: builder.push( ast.Name(top.get_value()) ) elif top.name == tok.NUMBER: - # builder.push( ast.Const(eval_number(top.get_value())) ) builder.push(NumberConst(eval_number(top.get_value()))) elif top.name == tok.STRING: # need to concatenate strings in atoms @@ -573,7 +564,6 @@ for token in atoms: assert isinstance(token, TokenObject) s += eval_string(token.get_value()) - # builder.push( ast.Const(s) ) builder.push(StringConst(s)) elif top.name == tok.BACKQUOTE: builder.push(ast.Backquote(atoms[1])) @@ -762,7 +752,6 @@ else: assert l==3 lvalue = atoms[0] - # assert is_augassign( lvalue ) assert isinstance(op, TokenObject) builder.push(ast.AugAssign(lvalue, op.get_name(), atoms[2])) @@ -780,7 +769,6 @@ for n in range(0,l,2): node = atoms[n] if isinstance(node, TokenObject) and node.name == tok.NEWLINE: - # nodes.append(ast.Discard(ast.Const(None))) nodes.append(ast.Discard(NoneConst())) else: nodes.append(node) @@ -791,13 +779,11 @@ if len(atoms) > 2: assert False, "return several stmts not implemented" elif len(atoms) == 1: - # builder.push(ast.Return(ast.Const(None), None)) # XXX lineno builder.push(ast.Return(NoneConst(), None)) # XXX lineno else: builder.push(ast.Return(atoms[1], None)) # XXX lineno def build_file_input(builder, nb): - # FIXME: need to handle docstring ! doc = None stmts = [] atoms = get_atoms(builder, nb) @@ -843,10 +829,8 @@ builder.push(ast.Tuple(items)) return -def build_varargslist(builder, nb): - pass - def build_lambdef(builder, nb): + """lambdef: 'lambda' [varargslist] ':' test""" atoms = get_atoms(builder, nb) code = atoms[-1] names, defaults, flags = parse_arglist(atoms[1:-2]) @@ -874,7 +858,6 @@ builder.push(SubscriptObject('subscript', subs, None)) elif len(atoms) == 2: # Attribute access: '.' NAME - # XXX Warning: fails if trailer is used in lvalue builder.push(atoms[0]) builder.push(atoms[1]) builder.push(TempRuleObject('pending-attr-access', 2, None)) @@ -882,10 +865,17 @@ assert False, "Trailer reducing implementation incomplete !" def build_arglist(builder, nb): + """ + arglist: (argument ',')* ( '*' test [',' '**' test] | + '**' test | + argument | + [argument ','] ) + """ atoms = get_atoms(builder, nb) arguments, stararg, dstararg = parse_argument(atoms) builder.push(ArglistObject(arguments, stararg, dstararg)) + def build_subscript(builder, nb): """'.' '.' '.' | [test] ':' [test] [':' [test]] | test""" atoms = get_atoms(builder, nb) @@ -923,7 +913,6 @@ sliceobj_infos = [] for value in sliceinfos: if value is None: - # sliceobj_infos.append(ast.Const(None)) sliceobj_infos.append(NoneConst()) else: sliceobj_infos.append(value) @@ -996,10 +985,6 @@ arglist = [] index = 3 arglist = atoms[3:-3] - # while not (isinstance(atoms[index], TokenObject) and atoms[index].name == tok.COLON): - # arglist.append(atoms[index]) - # index += 1 - # arglist.pop() # remove ':' names, default, flags = parse_arglist(arglist) funcname_token = atoms[1] assert isinstance(funcname_token, TokenObject) @@ -1007,7 +992,6 @@ arglist = atoms[2] code = atoms[-1] doc = get_docstring(code) - # FIXME: decorators and docstring ! builder.push(ast.Function(decorator_node, funcname, names, default, flags, doc, code)) @@ -1058,6 +1042,9 @@ def build_if_stmt(builder, nb): + """ + if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] + """ atoms = get_atoms(builder, nb) tests = [] tests.append((atoms[1], atoms[3])) @@ -1105,6 +1092,7 @@ builder.push(ast.For(assign, iterable, body, else_)) def build_exprlist(builder, nb): + """exprlist: expr (',' expr)* [',']""" atoms = get_atoms(builder, nb) if len(atoms) <= 2: builder.push(atoms[0]) @@ -1114,16 +1102,6 @@ names.append(atoms[index]) builder.push(ast.Tuple(names)) -def build_fplist(builder, nb): - """fplist: fpdef (',' fpdef)* [',']""" - atoms = get_atoms(builder, nb) - names = [] - for index in range(0, len(atoms), 2): - token = atoms[index] - assert isinstance(token, TokenObject) - names.append(token.get_value()) - builder.push(FPListObject('fplist', tuple(names), None)) - def build_while_stmt(builder, nb): """while_stmt: 'while' test ':' suite ['else' ':' suite]""" @@ -1339,7 +1317,6 @@ ASTRULES = { -# "single_input" : build_single_input, sym.atom : build_atom, sym.power : build_power, sym.factor : build_factor, @@ -1362,7 +1339,6 @@ sym.file_input : build_file_input, sym.testlist_gexp : build_testlist_gexp, sym.lambdef : build_lambdef, - sym.varargslist : build_varargslist, sym.trailer : build_trailer, sym.arglist : build_arglist, sym.subscript : build_subscript, @@ -1389,7 +1365,6 @@ sym.try_stmt : build_try_stmt, sym.exprlist : build_exprlist, sym.decorator : build_decorator, - # sym.fplist : build_fplist, } ## Stack elements definitions ################################### @@ -1405,7 +1380,7 @@ return "Const(%s)" % (repr(self.string_value),) def __eq__(self, other): - # XXX yurk : to make test pass + # XXX yurk : to make tests pass if other.__class__.__name__ == 'Const' and \ other.value == self.string_value: return True @@ -1440,29 +1415,40 @@ return True return False - -class RuleObject(ast.Node): - """A simple object used to wrap a rule or token""" - def __init__(self, name, count, src ): - self.name = name + +class BaseRuleObject(ast.Node): + """Base class for unnamed rules""" + def __init__(self, count, src): self.count = count self.line = 0 # src.getline() self.col = 0 # src.getcol() + + +class RuleObject(BaseRuleObject): + """A simple object used to wrap a rule or token""" + def __init__(self, name, count, src): + BaseRuleObject.__init__(self, count, src) + self.rulename = name def __str__(self): - return "" % (sym.sym_name[self.name], self.count) + return "" % (sym.sym_name[self.rulename], self.count) def __repr__(self): - return "" % (sym.sym_name[self.name], self.count) + return "" % (sym.sym_name[self.rulename], self.count) -class TempRuleObject(RuleObject): +class TempRuleObject(BaseRuleObject): """used to keep track of how many items get_atom() should pop""" + + def __init__(self, name, count, src): + BaseRuleObject.__init__(self, count, src) + self.temp_rulename = name + def __str__(self): - return "" % (self.name, self.count) + return "" % (self.temp_rulename, self.count) def __repr__(self): - return "" % (self.name, self.count) + return "" % (self.temp_rulename, self.count) class TokenObject(ast.Node): @@ -1483,7 +1469,6 @@ value = '' else: value = self.value - # assert isinstance(value, str) return value def __str__(self): @@ -1508,8 +1493,6 @@ def __repr__(self): return "" % (self.value,) -# FIXME: The ObjectAccessor family is probably not RPYTHON since -# some attributes have a different type depending on the subclass class ObjectAccessor(ast.Node): """base class for ArglistObject, SubscriptObject and SlicelistObject From tismer at codespeak.net Mon Aug 22 15:33:45 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 22 Aug 2005 15:33:45 +0200 (CEST) Subject: [pypy-svn] r16202 - pypy/dist/pypy/interpreter Message-ID: <20050822133345.C042B27B43@code1.codespeak.net> Author: tismer Date: Mon Aug 22 15:33:44 2005 New Revision: 16202 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: space/tab problem Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Mon Aug 22 15:33:44 2005 @@ -287,7 +287,7 @@ space.wrap(filename), space.wrap(mode)) code = space.interpclass_w(w_code) - from pypy.interpreter.pycode import PyCode + from pypy.interpreter.pycode import PyCode if not isinstance(code, PyCode): raise OperationError(space.w_RuntimeError, space.wrap("code object expected")) From hpk at codespeak.net Mon Aug 22 16:03:50 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 16:03:50 +0200 (CEST) Subject: [pypy-svn] r16203 - pypy/dist/pypy/documentation Message-ID: <20050822140350.781FA27B43@code1.codespeak.net> Author: hpk Date: Mon Aug 22 16:03:48 2005 New Revision: 16203 Modified: pypy/dist/pypy/documentation/ext-functions-draft.txt Log: fix ReST Modified: pypy/dist/pypy/documentation/ext-functions-draft.txt ============================================================================== --- pypy/dist/pypy/documentation/ext-functions-draft.txt (original) +++ pypy/dist/pypy/documentation/ext-functions-draft.txt Mon Aug 22 16:03:48 2005 @@ -23,3 +23,13 @@ * the backends will have implementations for these helper functions (to allow writing such implementations we will need a way to assign fixed names for some of the defined lltypes introduced by the rtyper) + +* XXX: integrate the following refinement:: + + interplevel: os.open() + annotation knows it returns an int. + rtyper knows to subst by a dummy ll_os_open + def ll_os_open(...): + fd = oslevel_open(...) + if fd == -1: + raise ... From hpk at codespeak.net Mon Aug 22 16:17:33 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 16:17:33 +0200 (CEST) Subject: [pypy-svn] r16204 - in pypy/branch/dist-newdoc: . lib-python pypy pypy/documentation pypy/module/__builtin__ Message-ID: <20050822141733.3095927B43@code1.codespeak.net> Author: hpk Date: Mon Aug 22 16:17:29 2005 New Revision: 16204 Added: pypy/branch/dist-newdoc/ - copied from r16185, pypy/dist/ pypy/branch/dist-newdoc/lib-python/ - copied from r16193, pypy/dist/lib-python/ pypy/branch/dist-newdoc/lib-python/conftest.py - copied unchanged from r16194, pypy/dist/lib-python/conftest.py pypy/branch/dist-newdoc/pypy/ - copied from r16202, pypy/dist/pypy/ pypy/branch/dist-newdoc/pypy/documentation/ext-functions-draft.txt - copied unchanged from r16203, pypy/dist/pypy/documentation/ext-functions-draft.txt Modified: pypy/branch/dist-newdoc/pypy/module/__builtin__/app_io.py Log: open up a branch for documentation separation by release and getting rid of the index.cgi? approach. This is experimental and might get postponed. Modified: pypy/branch/dist-newdoc/pypy/module/__builtin__/app_io.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_io.py (original) +++ pypy/branch/dist-newdoc/pypy/module/__builtin__/app_io.py Mon Aug 22 16:17:29 2005 @@ -4,6 +4,7 @@ """ import sys +import os def execfile(filename, glob=None, loc=None): if glob is None: From ludal at codespeak.net Mon Aug 22 16:19:11 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Mon, 22 Aug 2005 16:19:11 +0200 (CEST) Subject: [pypy-svn] r16205 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20050822141911.7BAB327B43@code1.codespeak.net> Author: ludal Date: Mon Aug 22 16:19:08 2005 New Revision: 16205 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/astgen.py pypy/dist/pypy/interpreter/astcompiler/consts.py pypy/dist/pypy/interpreter/astcompiler/future.py pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/astcompiler/symbols.py pypy/dist/pypy/interpreter/astcompiler/syntax.py pypy/dist/pypy/interpreter/astcompiler/transformer.py pypy/dist/pypy/interpreter/astcompiler/visitor.py Log: (ludal, nik) + port modifications from stablecompiler to astcompiler + modify astgen.py so that it doesn't generate __eq__ on ast.Node Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Mon Aug 22 16:19:08 2005 @@ -33,23 +33,6 @@ pass # implemented by subclasses def visit(self, visitor, *args): return visitor.visitNode(self, *args) - def __eq__(self, right): - if type(self) != type(right): - return False - # the following tests prevnts Node1([foo]) and Node2([foo]) - # from being equals. compare __name__ because class will - # be different (astcompiler.class1 and stablecompiler.class1 should - # be seen as equals) - if self.__class__.__name__ != right.__class__.__name__: - return False - self_child = self.getChildren() - right_child = right.getChildren() - if len(self_child) != len(right_child): - return False - for i,j in zip(self_child, right_child): - if not i==j: - return False - return True class EmptyNode(Node): def visit(self, visitor, *args): @@ -987,7 +970,6 @@ def accept(self, visitor, args): return visitor.visitListComp(self, args) - class ListCompFor(Node): def __init__(self, assign, list, ifs, lineno=None): self.assign = assign Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Mon Aug 22 16:19:08 2005 @@ -296,13 +296,6 @@ pass # implemented by subclasses def visit(self, visitor, *args): return visitor.visitNode(self, *args) - def __eq__(self, right): - if type(self)!=type(right): - return False - for i,j in zip(self.getChildren(),right.getChildren()): - if not i==j: - return False - return True class EmptyNode(Node): def visit(self, visitor, *args): Modified: pypy/dist/pypy/interpreter/astcompiler/consts.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/consts.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/consts.py Mon Aug 22 16:19:08 2005 @@ -8,6 +8,7 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 +SC_REALLY_GLOBAL = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/interpreter/astcompiler/future.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/future.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/future.py Mon Aug 22 16:19:08 2005 @@ -2,7 +2,7 @@ """ -from compiler import ast, walk +from pypy.interpreter.astcompiler import ast, walk def is_future(stmt): """Return true if statement is a well-formed future statement""" @@ -61,7 +61,7 @@ if __name__ == "__main__": import sys - from compiler import parseFile, walk + from pypy.interpreter.astcompiler import parseFile, walk for file in sys.argv[1:]: print file Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Mon Aug 22 16:19:08 2005 @@ -5,8 +5,8 @@ import sys import types -from compiler import misc -from compiler.consts \ +from pypy.interpreter.astcompiler import misc +from pypy.interpreter.astcompiler.consts \ import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS class FlowGraph: @@ -81,6 +81,9 @@ i.e. each node appears before all of its successors """ + # TODO: What we need here is a topological sort that + + # XXX make sure every node that doesn't have an explicit next # is set so that next points to exit for b in self.blocks.elements(): @@ -244,7 +247,7 @@ op = inst[0] if op[:4] == 'JUMP': self.outEdges.add(inst[1]) - self.insts.append(inst) + self.insts.append( list(inst) ) def getInstructions(self): return self.insts @@ -343,6 +346,7 @@ if isinstance(var, TupleArg): self.varnames[i] = var.getName() self.stage = RAW + self.orderedblocks = [] def setDocstring(self, doc): self.docstring = doc @@ -366,10 +370,10 @@ """Get a Python code object""" if self.stage == RAW: self.computeStackDepth() - self.flattenGraph() - if self.stage == FLAT: self.convertArgs() if self.stage == CONV: + self.flattenGraph() + if self.stage == FLAT: self.makeByteCode() if self.stage == DONE: return self.newCodeObject() @@ -425,35 +429,64 @@ def flattenGraph(self): """Arrange the blocks in order and resolve jumps""" - assert self.stage == RAW + assert self.stage == CONV self.insts = insts = [] pc = 0 begin = {} end = {} - for b in self.getBlocksInOrder(): + forward_refs = [] + for b in self.orderedblocks: begin[b] = pc for inst in b.getInstructions(): - insts.append(inst) if len(inst) == 1: + insts.append(inst) pc = pc + 1 elif inst[0] != "SET_LINENO": - # arg takes 2 bytes - pc = pc + 3 + opname, arg = inst + if self.hasjrel.has_elt(opname): + # relative jump - no extended arg + forward_refs.append( (arg, inst, pc ) ) + insts.append(inst) + pc = pc + 3 + elif self.hasjabs.has_elt(opname): + # absolute jump - can be extended if backward + if arg in begin: + # can only extend argument if backward + offset = begin[arg] + hi, lo = divmod(offset,65536) + if hi>0: + # extended argument + insts.append( ["EXTENDED_ARG", hi ] ) + pc = pc + 3 + inst[1] = lo + else: + forward_refs.append( (arg, inst, pc ) ) + insts.append(inst) + pc = pc + 3 + else: + # numerical arg + assert type(arg)==int + hi,lo = divmod(arg,65536) + if hi>0: + # extended argument + insts.append( ["EXTENDED_ARG", hi ] ) + inst[1] = lo + pc = pc + 3 + insts.append(inst) + pc = pc + 3 + else: + insts.append(inst) end[b] = pc pc = 0 - for i in range(len(insts)): - inst = insts[i] - if len(inst) == 1: - pc = pc + 1 - elif inst[0] != "SET_LINENO": - pc = pc + 3 - opname = inst[0] + + for arg, inst, pc in forward_refs: + opname, block = inst + abspos = begin[block] if self.hasjrel.has_elt(opname): - oparg = inst[1] - offset = begin[oparg] - pc - insts[i] = opname, offset - elif self.hasjabs.has_elt(opname): - insts[i] = opname, begin[inst[1]] + offset = abspos - pc - 3 + inst[1] = offset + else: + inst[1] = abspos self.stage = FLAT hasjrel = misc.Set() @@ -465,16 +498,18 @@ def convertArgs(self): """Convert arguments from symbolic to concrete form""" - assert self.stage == FLAT + assert self.stage == RAW + self.orderedblocks = self.getBlocksInOrder() self.consts.insert(0, self.docstring) self.sort_cellvars() - for i in range(len(self.insts)): - t = self.insts[i] - if len(t) == 2: - opname, oparg = t - conv = self._converters.get(opname, None) - if conv: - self.insts[i] = opname, conv(self, oparg) + + for b in self.orderedblocks: + for inst in b.getInstructions(): + if len(inst) == 2: + opname, oparg = inst + conv = self._converters.get(opname, None) + if conv: + inst[1] = conv(self, oparg) self.stage = CONV def sort_cellvars(self): @@ -563,10 +598,15 @@ del name, obj, opname def makeByteCode(self): - assert self.stage == CONV + assert self.stage == FLAT self.lnotab = lnotab = LineAddrTable() for t in self.insts: opname = t[0] + if self._debug: + if len(t)==1: + print "x",opname + else: + print "x",opname, t[1] if len(t) == 1: lnotab.addCode(self.opnum[opname]) else: Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Mon Aug 22 16:19:08 2005 @@ -6,12 +6,13 @@ import types from cStringIO import StringIO -from compiler import ast, parse, walk, syntax -from compiler import pyassem, misc, future, symbols -from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL -from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\ - CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION -from compiler.pyassem import TupleArg +from pypy.interpreter.astcompiler import ast, parse, walk, syntax +from pypy.interpreter.astcompiler import pyassem, misc, future, symbols +from pypy.interpreter.astcompiler.consts import SC_LOCAL, SC_GLOBAL, \ + SC_FREE, SC_CELL, SC_REALLY_GLOBAL +from pypy.interpreter.astcompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \ + CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION +from pypy.interpreter.astcompiler.pyassem import TupleArg # XXX The version-specific code can go, since this code only works with 2.x. # Do we have Python 1.x or Python 2.x? @@ -285,6 +286,8 @@ self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) + elif scope == SC_REALLY_GLOBAL: + self.emit(prefix + '_GLOBAL', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Mon Aug 22 16:19:08 2005 @@ -1,8 +1,9 @@ """Module symbol-table generator""" -from compiler import ast -from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_UNKNOWN -from compiler.misc import mangle +from pypy.interpreter.astcompiler import ast +from pypy.interpreter.astcompiler.consts import SC_LOCAL, SC_GLOBAL, \ + SC_FREE, SC_CELL, SC_UNKNOWN, SC_REALLY_GLOBAL +from pypy.interpreter.astcompiler.misc import mangle import types @@ -89,7 +90,7 @@ The scope of a name could be LOCAL, GLOBAL, FREE, or CELL. """ if self.globals.has_key(name): - return SC_GLOBAL + return SC_REALLY_GLOBAL if self.cells.has_key(name): return SC_CELL if self.defs.has_key(name): @@ -154,7 +155,7 @@ if sc == SC_UNKNOWN or sc == SC_FREE \ or isinstance(self, ClassScope): self.frees[name] = 1 - elif sc == SC_GLOBAL: + elif sc == SC_GLOBAL or sc == SC_REALLY_GLOBAL: child_globals.append(name) elif isinstance(self, FunctionScope) and sc == SC_LOCAL: self.cells[name] = 1 @@ -419,7 +420,7 @@ if __name__ == "__main__": import sys - from compiler import parseFile, walk + from pypy.interpreter.astcompiler import parseFile, walk import symtable def get_names(syms): Modified: pypy/dist/pypy/interpreter/astcompiler/syntax.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/syntax.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/syntax.py Mon Aug 22 16:19:08 2005 @@ -9,7 +9,7 @@ errors. """ -from compiler import ast, walk +from pypy.interpreter.astcompiler import ast, walk def check(tree, multi=None): v = SyntaxErrorChecker(multi) Modified: pypy/dist/pypy/interpreter/astcompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/transformer.py Mon Aug 22 16:19:08 2005 @@ -27,10 +27,12 @@ # http://www.opensource.org/licenses/bsd-license.html # and replace OWNER, ORGANIZATION, and YEAR as appropriate. -from compiler.ast import * +# make sure we import the parser with the correct grammar +import pypy.interpreter.pyparser.pythonparse +from pypy.interpreter.stablecompiler.ast import * import parser -import symbol -import token +import pypy.interpreter.pyparser.pysymbol as symbol +import pypy.interpreter.pyparser.pytoken as token import sys class WalkerError(StandardError): @@ -171,7 +173,6 @@ def single_input(self, node): ### do we want to do anything about being "interactive" ? - # NEWLINE | simple_stmt | compound_stmt NEWLINE n = node[0][0] if n != token.NEWLINE: @@ -780,7 +781,6 @@ names = [] defaults = [] flags = 0 - i = 0 while i < len(nodelist): node = nodelist[i] Modified: pypy/dist/pypy/interpreter/astcompiler/visitor.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/visitor.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/visitor.py Mon Aug 22 16:19:08 2005 @@ -1,4 +1,4 @@ -from compiler import ast +from pypy.interpreter.astcompiler import ast # XXX should probably rename ASTVisitor to ASTWalker # XXX can it be made even more generic? From ludal at codespeak.net Mon Aug 22 16:21:08 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Mon, 22 Aug 2005 16:21:08 +0200 (CEST) Subject: [pypy-svn] r16206 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050822142108.4ECBE27B47@code1.codespeak.net> Author: ludal Date: Mon Aug 22 16:21:06 2005 New Revision: 16206 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: (ludal,nik) - implement nodes_equal function here since we got rid of Node.__eq__ (renders Node type unhashable) Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Mon Aug 22 16:21:06 2005 @@ -4,10 +4,24 @@ from pypy.interpreter.pyparser.astbuilder import AstBuilder from pypy.interpreter.pyparser.pythonutil import ast_from_input from pypy.interpreter.stablecompiler.transformer import Transformer +import pypy.interpreter.stablecompiler.ast as stable_ast +import pypy.interpreter.astcompiler.ast as ast_ast + import py.test from pypy.interpreter.astcompiler import ast + +def nodes_equal(left, right): + if type(left)!=type(right): + return False + if not isinstance(left,stable_ast.Node) or not isinstance(right,ast_ast.Node): + return left==right + for i,j in zip(left.getChildren(),right.getChildren()): + if not nodes_equal(i,j): + return False + return True + expressions = [ "x = a + 1", "x = 1 - a", @@ -392,7 +406,7 @@ print "BUILT:", r1.rule_stack[-1] print "-" * 30 # r1.rule_stack[-1].equals(ast) - assert ast == r1.rule_stack[-1], 'failed on %r' % (expr) + assert nodes_equal( ast, r1.rule_stack[-1]), 'failed on %r' % (expr) def test_basic_astgen(): @@ -472,3 +486,4 @@ ] for data in test: assert eval_string(data) == eval(data) + From hpk at codespeak.net Mon Aug 22 16:24:41 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 16:24:41 +0200 (CEST) Subject: [pypy-svn] r16207 - in pypy/branch/dist-newdoc/pypy/documentation: . website Message-ID: <20050822142441.5718B27B43@code1.codespeak.net> Author: hpk Date: Mon Aug 22 16:24:39 2005 New Revision: 16207 Added: pypy/branch/dist-newdoc/pypy/documentation/confrest.py (contents, props changed) pypy/branch/dist-newdoc/pypy/documentation/contact.txt - copied unchanged from r16204, pypy/branch/dist-newdoc/pypy/documentation/website/contact.txt pypy/branch/dist-newdoc/pypy/documentation/news.txt - copied unchanged from r16204, pypy/branch/dist-newdoc/pypy/documentation/website/news.txt Removed: pypy/branch/dist-newdoc/pypy/documentation/website/contact.txt pypy/branch/dist-newdoc/pypy/documentation/website/news.txt Log: first steps at statically generating pypy pages statically. Also removing the website subdirectory because it is not really helpful and would be ugly in the resulting URLs Added: pypy/branch/dist-newdoc/pypy/documentation/confrest.py ============================================================================== --- (empty file) +++ pypy/branch/dist-newdoc/pypy/documentation/confrest.py Mon Aug 22 16:24:39 2005 @@ -0,0 +1,28 @@ +from py.__.documentation.confrest import * + +class PyPyPage(Page): + def fill(self): + super(PyPyPage, self).fill() + self.menubar[:] = html.div( + html.a("news", href="news.html", class_="menu"), " ", + html.a("doc", href="index.html", class_="menu"), " ", + html.a("contact", href="contact.html", class_="menu"), " ", + html.a("getting-started", href="getting_started.html", class_="menu"), " ", + html.a("issue", + href="https://codespeak.net/issue/pypy-dev/", + class_="menu"), + " ", id="menubar") + + +class Project(Project): + title = "PyPy" + stylesheet = 'style.css' + encoding = 'latin1' + prefix_title = "PyPy" + logo = html.div( + html.a( + html.img(alt="PyPy", height="110", id="pyimg", + src="/pypy/img/py-web1.png", width="149"))) + Page = PyPyPage + + Deleted: /pypy/branch/dist-newdoc/pypy/documentation/website/contact.txt ============================================================================== --- /pypy/branch/dist-newdoc/pypy/documentation/website/contact.txt Mon Aug 22 16:24:39 2005 +++ (empty file) @@ -1,37 +0,0 @@ -PyPy mailing lists -================== - -* `development mailing list`_ for conceptual and coding discussions (low to medium traffic). - -* `subversion commit mailing list`_ all updates to the trunk/branch source and documentation tree. - -* `sprint mailing list`_ for people (interested in) attending upcoming sprints. - -* `EU partner mailing list`_ for people involved with EU administrative details - -.. _`sprint mailing list`: http://codespeak.net/mailman/listinfo/pypy-sprint -.. _`subversion commit mailing list`: http://codespeak.net/mailman/listinfo/pypy-svn -.. _`development mailing list`: http://codespeak.net/mailman/listinfo/pypy-dev -.. _`EU partner mailing list`: http://codespeak.net/mailman/listinfo/pypy-funding - - -PyPy issue trackers -=================== - -* `development bug/feature tracker`_ for filing bugs and feature requests. - -* `EU milestone/issue tracking`_ for organizing work on EU-project milestones and deliverables - -.. _`EU milestone/issue tracking`: https://codespeak.net/issue/pypy-eu/ - -.. _`development bug/feature tracker`: https://codespeak.net/issue/pypy-dev/ - -IRC Channel #pypy on freenode -============================= - -Many of the core developers are hanging out at #pypy on irc.freenode.net. -You are welcome to join and ask questions even more so if you are interested -in participating in some parts of the PyPy project. You can find the logs of -the channel here_. - -.. _here: http://nimrod.terra-link.net/pypy \ No newline at end of file Deleted: /pypy/branch/dist-newdoc/pypy/documentation/website/news.txt ============================================================================== --- /pypy/branch/dist-newdoc/pypy/documentation/website/news.txt Mon Aug 22 16:24:39 2005 +++ (empty file) @@ -1,86 +0,0 @@ - - - The PyPy project aims at producing a flexible and fast Python_ - implementation. The guiding idea is to translate a Python-level - description of the Python language itself to lower level languages. - Rumors have it that the secret goal is being faster-than-C which is - nonsense, isn't it? `more...`_ - -.. _Python: http://www.python.org/doc/current/ref/ref.html -.. _`more...`: ../architecture.html#mission-statement - -Next PyPy Sprint in Heidelberg 22nd-29th August 2005 -====================================================== - -The next PyPy sprint will take place at the Heidelberg University -in Germany from 22nd August to 29th August (both days included). -Its main focus is translation of the whole PyPy interpreter -to a low level language and reaching 2.4.1 Python compliancy. -The goal of the sprint is to release a first self-contained PyPy-0.7 version. -To learn more see the `Heidelberg sprint announcement`_ or look at -the list of people_ that are expected to come. - -.. _people: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/heidelberg-people.html -.. _`Heidelberg sprint announcement`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/Heidelberg-sprint.html - - -PyPy Hildesheim2 finished: first self-contained PyPy run! -=========================================================== - -Up until 31st August we were in a PyPy sprint at `Trillke-Gut`_. -Carl has written a `report about day 1`_, Holger -about `day 2 and day 3`_ and Carl again about `day 4 and day 5`_, -On `day 6`_ Holger reports the `breakthrough`_: PyPy runs -on its own! Hurray_!. And Carl finally reports about the winding -down of `day 7`_ which saw us relaxing, discussing and generally -having a good time. You might want to look at the selected -`pictures from the sprint`_. - -.. _`report about day 1`: http://codespeak.net/pipermail/pypy-dev/2005q3/002217.html -.. _`day 2 and day 3`: http://codespeak.net/pipermail/pypy-dev/2005q3/002220.html -.. _`day 4 and day 5`: http://codespeak.net/pipermail/pypy-dev/2005q3/002234.html -.. _`day 6`: http://codespeak.net/pipermail/pypy-dev/2005q3/002239.html -.. _`day 7`: http://codespeak.net/pipermail/pypy-dev/2005q3/002245.html -.. _`breakthrough`: http://codespeak.net/~hpk/hildesheim2-sprint-www/hildesheim2-sprint-www-Thumbnails/36.jpg -.. _`hurray`: http://codespeak.net/~hpk/hildesheim2-sprint-www/hildesheim2-sprint-www-Pages/Image37.html -.. _`pictures from the sprint`: http://codespeak.net/~hpk/hildesheim2-sprint-www/ -.. _`Trillke-Gut`: http://www.trillke.net/images/HomePagePictureSmall.jpg - -EuroPython 2005 sprints finished -====================================================== - -We had two sprints around EuroPython, one more internal core -developer one and a public one. Both sprints were quite -successful. Regarding the Pre-EuroPython sprint Michael Hudson -has posted summaries of `day 1`_, `day 2`_ and `day 3`_ on -the `pypy-dev`_ mailing list. The larger public sprint -has not been summarized yet but it went very well. We had -20 people initially attending to hear the tutorials and -work a bit. Later with around 13-14 people we made the -move to Python-2.4.1, integrated the parser, improved -the LLVM backends and type inference in general. -*(07/13/2005)* - -.. _`day 1`: http://codespeak.net/pipermail/pypy-dev/2005q2/002169.html -.. _`day 2`: http://codespeak.net/pipermail/pypy-dev/2005q2/002171.html -.. _`day 3`: http://codespeak.net/pipermail/pypy-dev/2005q2/002172.html -.. _`pypy-dev`: http://codespeak.net/mailman/listinfo/pypy-dev - -.. _EuroPython: http://europython.org -.. _`translation`: ../translation.html -.. _`sprint announcement`: EP2005-announcement.html -.. _`list of people coming`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/EP2005-people.html - -First PyPy release! -=================== - -We are happy to announce the first public release of PyPy after two years of -spare-time and half a year of EU funded development. The 0.6 release is -a preview release, concentrating on CPython compatibility, good documentation -and nice starting points into the PyPy code base. We invite you to head -over to the `getting started`_ document or read more in the -`release announcement`_. *(05/20/2005)* - -.. _`release announcement`: http://codespeak.net/pypy/index.cgi?doc/release-0.6.html -.. _`getting started`: http://codespeak.net/pypy/index.cgi?getting-started - From ludal at codespeak.net Mon Aug 22 16:28:19 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Mon, 22 Aug 2005 16:28:19 +0200 (CEST) Subject: [pypy-svn] r16208 - in pypy/dist/pypy: interpreter interpreter/pyparser tool Message-ID: <20050822142819.57B5727B47@code1.codespeak.net> Author: ludal Date: Mon Aug 22 16:28:17 2005 New Revision: 16208 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/pythonutil.py pypy/dist/pypy/tool/option.py Log: (ludal,nik) - adds an PythonAstCompiler class that uses the astbuilder module - provide a command line option --compiler=astparser to use it Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Aug 22 16:28:17 2005 @@ -1,7 +1,7 @@ from pypy.interpreter.executioncontext import ExecutionContext from pypy.interpreter.error import OperationError from pypy.interpreter.argument import Arguments -from pypy.interpreter.pycompiler import CPythonCompiler +from pypy.interpreter.pycompiler import CPythonCompiler, PythonAstCompiler from pypy.interpreter.pycompiler import PythonCompiler, PyPyCompiler from pypy.interpreter.miscutils import ThreadLocals from pypy.tool.cache import Cache @@ -258,6 +258,8 @@ compiler = PythonCompiler(self) elif self.options.compiler == 'cpython': compiler = CPythonCompiler(self) + elif self.options.compiler == 'astparser': + compiler = PythonAstCompiler(self) else: raise ValueError('unknown --compiler option value: %r' % ( self.options.compiler,)) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Mon Aug 22 16:28:17 2005 @@ -232,7 +232,6 @@ return PyCode(space)._from_code(c) compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' - class PythonCompilerApp(PythonCompiler): """Temporary. Calls the stablecompiler package at app-level.""" @@ -294,6 +293,64 @@ return code +class PythonAstCompiler(CPythonCompiler): + """Uses the stdlib's python implementation of compiler + + XXX: This class should override the baseclass implementation of + compile_command() in order to optimize it, especially in case + of incomplete inputs (e.g. we shouldn't re-compile from sracth + the whole source after having only added a new '\n') + """ + def compile(self, source, filename, mode, flags): + from pyparser.error import ParseError + from pyparser.pythonutil import internal_pypy_parse_to_ast + flags |= __future__.generators.compiler_flag # always on (2.2 compat) + # XXX use 'flags' + space = self.space + try: + encoding, ast_tree = internal_pypy_parse_to_ast(source, mode, True, flags) + except ParseError, e: + raise OperationError(space.w_SyntaxError, + e.wrap_info(space, filename)) + return self.compile_parse_result(ast_tree, filename, mode) + + def compile_parse_result(self, ast_tree, filename, mode): + """NOT_RPYTHON""" + # __________ + # XXX this uses the non-annotatable astcompiler at interp-level + from pypy.interpreter import astcompiler + from pypy.interpreter.astcompiler.pycodegen import ModuleCodeGenerator + from pypy.interpreter.astcompiler.pycodegen import InteractiveCodeGenerator + from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator + space = self.space + try: + astcompiler.misc.set_filename(filename, ast_tree) ### TODO: doesn't work + if mode == 'exec': + codegenerator = ModuleCodeGenerator(ast_tree) + elif mode == 'single': + codegenerator = InteractiveCodeGenerator(ast_tree) + else: # mode == 'eval': + codegenerator = ExpressionCodeGenerator(ast_tree) + c = codegenerator.getCode() + except SyntaxError, e: + w_synerr = space.newtuple([space.wrap(e.msg), + space.newtuple([space.wrap(e.filename), + space.wrap(e.lineno), + space.wrap(e.offset), + space.wrap(e.text)])]) + raise OperationError(space.w_SyntaxError, w_synerr) + except ValueError,e: + raise OperationError(space.w_ValueError,space.wrap(str(e))) + except TypeError,e: + raise + raise OperationError(space.w_TypeError,space.wrap(str(e))) + # __________ end of XXX above + from pypy.interpreter.pycode import PyCode + return PyCode(space)._from_code(c) + compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' + + + class PyPyCompiler(CPythonCompiler): """Uses the PyPy implementation of Compiler Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Aug 22 16:28:17 2005 @@ -413,6 +413,7 @@ from pypy.objspace.std.strutil import ParseStringError if value.endswith('l') or value.endswith('L'): value = value[:-1] + return string_to_long(value) # ??? try: return string_to_int(value) except ParseStringError: Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Mon Aug 22 16:28:17 2005 @@ -107,6 +107,15 @@ PYTHON_PARSER.parse_source(input, target, builder) return builder.rule_stack[-1] + +def internal_pypy_parse_to_ast(source, mode='exec', lineno=False, flags=0): + builder = AstBuilder() + target_rule = TARGET_DICT[mode] + PYTHON_PARSER.parse_source(source, target_rule, builder, flags) + ast_tree = builder.rule_stack[-1] + return (builder.source_encoding, ast_tree) + + ## TARGET FOR ANNOTATORS ############################################# def annotateme(source): """This function has no other role than testing the parser's annotation Modified: pypy/dist/pypy/tool/option.py ============================================================================== --- pypy/dist/pypy/tool/option.py (original) +++ pypy/dist/pypy/tool/option.py Mon Aug 22 16:28:17 2005 @@ -13,8 +13,9 @@ nofaking = 0 parser = "recparser" # "cpython" / "recparser" / "parser" compiler = "pyparse" # "cpython" - # "pyparse" pypy parser, cpython's compiler package + # "pyparse" pypy parser, cpython's compiler and transformer package # "pyparseapp" same, running the compiler at app-level + # "astparser" pypy parser with ast builder using cpython's compiler # "pycomp" pypy parser and compiler (TBD) usemodules = [] version = "2.4" # "native" / "2.3" / "2.4" @@ -55,7 +56,7 @@ options.append(make_option( '--compiler', action="store", type="string", dest="compiler", help="select the compiler approach to use internally", - metavar="[pyparser|cpython|pyparseapp]")) + metavar="[pyparse|astparser|cpython|pyparseapp]")) options.append(make_option( '--parser', action="store",type="string", dest="parser", help="select the parser module to use", From ale at codespeak.net Mon Aug 22 16:30:28 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 22 Aug 2005 16:30:28 +0200 (CEST) Subject: [pypy-svn] r16209 - pypy/dist/pypy/module/_codecs/test Message-ID: <20050822143028.98A3727B43@code1.codespeak.net> Author: ale Date: Mon Aug 22 16:30:27 2005 New Revision: 16209 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: A test taking from lib-python/test_codecs.py Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Mon Aug 22 16:30:27 2005 @@ -1,6 +1,20 @@ import autopath class AppTestCodecs: + def test_seek_utf16le(self): + # all codecs should be able to encode these + import codecs, StringIO + encoding = 'utf-16-le' + s = u"%s\n%s\n" % (10*u"abc123", 10*u"def456") + reader = codecs.getreader(encoding)(StringIO.StringIO(s.encode(encoding))) + for t in xrange(5): + # Test that calling seek resets the internal codec state and buffers + reader.seek(0, 0) + print "before" + line = reader.readline() + print "after",line + assert s[:len(line)] == line + def test_unicode_internal_encode(self): import sys From ludal at codespeak.net Mon Aug 22 16:43:08 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Mon, 22 Aug 2005 16:43:08 +0200 (CEST) Subject: [pypy-svn] r16210 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050822144308.CBE6327B43@code1.codespeak.net> Author: ludal Date: Mon Aug 22 16:43:07 2005 New Revision: 16210 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py Log: (ludal,nik) + implemented getChildren correctly on NumberConst, NoneConst and StringConst + remove __eq__ from the same classes Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Mon Aug 22 16:43:07 2005 @@ -1380,12 +1380,8 @@ def __repr__(self): return "Const(%s)" % (repr(self.string_value),) - def __eq__(self, other): - # XXX yurk : to make tests pass - if other.__class__.__name__ == 'Const' and \ - other.value == self.string_value: - return True - return False + def getChildren(self): + return self.string_value, class NumberConst(ast.Const): """specific Const node for numbers""" @@ -1398,11 +1394,8 @@ def __repr__(self): return "Const(%s)" % (repr(self.number_value),) - def __eq__(self, other): - if other.__class__.__name__ == 'Const' and \ - other.value == self.number_value: - return True - return False + def getChildren(self): + return self.number_value, class NoneConst(ast.Const): """specific Const node for None (probably not really needed)""" @@ -1410,12 +1403,6 @@ self.lineno = lineno self.value = None - def __eq__(self, other): - if other.__class__.__name__ == 'Const' and \ - other.value is None: - return True - return False - class BaseRuleObject(ast.Node): """Base class for unnamed rules""" From hpk at codespeak.net Mon Aug 22 16:50:12 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 16:50:12 +0200 (CEST) Subject: [pypy-svn] r16211 - in pypy/branch/dist-newdoc/pypy/documentation: . website Message-ID: <20050822145012.DC7C127B43@code1.codespeak.net> Author: hpk Date: Mon Aug 22 16:49:59 2005 New Revision: 16211 Added: pypy/branch/dist-newdoc/pypy/documentation/getting-started.txt - copied unchanged from r16204, pypy/branch/dist-newdoc/pypy/documentation/getting_started.txt Removed: pypy/branch/dist-newdoc/pypy/documentation/getting_started.txt pypy/branch/dist-newdoc/pypy/documentation/website/ Modified: pypy/branch/dist-newdoc/pypy/documentation/architecture.txt pypy/branch/dist-newdoc/pypy/documentation/confrest.py pypy/branch/dist-newdoc/pypy/documentation/index.txt pypy/branch/dist-newdoc/pypy/documentation/news.txt pypy/branch/dist-newdoc/pypy/documentation/objspace.txt pypy/branch/dist-newdoc/pypy/documentation/redirections pypy/branch/dist-newdoc/pypy/documentation/release-0.6.txt pypy/branch/dist-newdoc/pypy/documentation/translation.txt Log: more reshufflings towards a flatter doc hierarchy Modified: pypy/branch/dist-newdoc/pypy/documentation/architecture.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/architecture.txt (original) +++ pypy/branch/dist-newdoc/pypy/documentation/architecture.txt Mon Aug 22 16:49:59 2005 @@ -8,7 +8,7 @@ This document gives an overview of the goals and architecture of PyPy. See also `getting started`_ for a practical introduction. -.. _`getting started`: getting_started.html +.. _`getting started`: getting-started.html Mission statement Modified: pypy/branch/dist-newdoc/pypy/documentation/confrest.py ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/confrest.py (original) +++ pypy/branch/dist-newdoc/pypy/documentation/confrest.py Mon Aug 22 16:49:59 2005 @@ -7,12 +7,12 @@ html.a("news", href="news.html", class_="menu"), " ", html.a("doc", href="index.html", class_="menu"), " ", html.a("contact", href="contact.html", class_="menu"), " ", - html.a("getting-started", href="getting_started.html", class_="menu"), " ", + html.a("getting-started", + href="getting_started.html", class_="menu"), " ", html.a("issue", href="https://codespeak.net/issue/pypy-dev/", class_="menu"), " ", id="menubar") - class Project(Project): title = "PyPy" @@ -21,8 +21,9 @@ prefix_title = "PyPy" logo = html.div( html.a( - html.img(alt="PyPy", height="110", id="pyimg", - src="/pypy/img/py-web1.png", width="149"))) + html.img(alt="PyPy", id="pyimg", + src="http://codespeak.net/pypy/img/py-web1.png", + height=110, width=149))) Page = PyPyPage Deleted: /pypy/branch/dist-newdoc/pypy/documentation/getting_started.txt ============================================================================== --- /pypy/branch/dist-newdoc/pypy/documentation/getting_started.txt Mon Aug 22 16:49:59 2005 +++ (empty file) @@ -1,560 +0,0 @@ -================================== -PyPy - Getting Started -================================== - -.. contents:: -.. sectnum:: - -.. _howtopypy: - -Just the facts -============== - -getting & running the PyPy 0.6.1 release ------------------------------------------ - - Note that the 0.6 release was broken and - thus you find only the 0.6.1 release here. - -Download one of the following release files and unpack it: - -*pypy-0.6.1 (05/21/2005)* - - * download one of `pypy-0.6.1.tar.bz2`_, `pypy-0.6.1.tar.gz`_ or - `pypy-0.6.1.zip`_ (windows line-endings) and unpack it - - * alternatively run ``svn co http://codespeak.net/svn/pypy/release/0.6.1 pypy-0.6.1`` - -then change to the ``pypy-0.6.1`` directory -and execute the following command line:: - - python pypy/bin/py.py - -This will give you a PyPy prompt, i.e. a very compliant -Python interpreter implemented in Python. Because this version -of PyPy still runs on top of CPython, it runs around 2000 -times slower than the original CPython. The release focus -really was on compliancy: PyPy passes around `90% of CPythons core -language regression tests`_. - -Have a look at `interesting starting points`_ -for guidance on how to continue. - -.. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.6.1.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.6.1.tar.bz2 -.. _`pypy-0.6.1.zip`: http://codespeak.net/download/pypy/pypy-0.6.1.zip -.. _`pypy-0.6.1.tar.gz`: http://codespeak.net/download/pypy/pypy-0.6.1.tar.gz - -Svn-check out & run the latest PyPy as a two-liner --------------------------------------------------- - -If you want to play with the ongoing development PyPy version -you can check it out from the repository using subversion. Download -and install subversion_ if you don't allready have it. Then you can -issue on the command line (DOS box or terminal):: - - svn co http://codespeak.net/svn/pypy/dist pypy-dist - -This will create a directory named ``pypy-dist``, and will get you the PyPy -source in ``pypy-dist/pypy`` and documentation files in -``pypy-dist/pypy/documentation``. - -After checkout you can get a PyPy interpreter via:: - - python pypy-dist/pypy/bin/py.py - -have fun :-) - -We have some `help on installing subversion`_ for PyPy. -Have a look at `interesting starting points`_ -for some guidance on how to continue. - -.. _`help on installing subversion`: svn-help.html -.. _subversion: svn-help.html - -Understanding PyPy's architecture ---------------------------------- - -For in-depth information about architecture and coding documentation -head over to the `documentation section`_ where you'll find lots of -interesting information. Additionally, in true hacker spirit, you -may just `start reading sources`_ . - -.. _`documentation section`: index.html - -running all of PyPy's tests ---------------------------- - -If you want to see if PyPy works on your machine/platform -you can simply run PyPy's large test suite with:: - - python pypy/test_all.py - -test_all.py is just another name for `py.test`_ which is the -testing tool that we are using and enhancing for PyPy. - -Filing bugs or feature requests -------------------------------- - -You may file `bug reports`_ on our issue tracker which is -also accessible through the 'issues' top menu of -the PyPy website. `using the development tracker`_ has -more detailed information on specific features of the tracker. - -.. _`using the development tracker`: coding-guide.html#using-development-tracker - -.. _`interesting starting points`: - -Interesting Starting Points in PyPy -=================================== - -The following assumes that you have successfully downloaded and extracted the -PyPy release or have checked out PyPy using svn. It assumes that you are in -the top level directory of the PyPy source tree, e.g. pypy-x.x (if you -got a release) or pypy-dist (if you checked out the most recent version using -subversion). - -Main entry point ------------------------------------------- - -The py.py interpreter -+++++++++++++++++++++ - -To start interpreting Python with PyPy, use Python 2.3 or greater:: - - cd pypy/bin - python py.py - -After a few seconds (remember: this is running on top of CPython), -you should be at the PyPy prompt, which is the same as the Python -prompt, but with an extra ">". - -Now you are ready to start running Python code. Most Python -modules should work if they don't involve CPython extension -modules. Here is an example of determining PyPy's performance -in pystones:: - - >>>> from test import pystone - >>>> pystone.main(10) - -Note that this is a slightly modified version of pystone -- the -original version does not accept the parameter to main(). The -parameter is the number of loops to run through the test, and the -default is 50000, which is far too many to run in a reasonable time -on the current PyPy implementation. - -py.py options -+++++++++++++ - -To list the PyPy interpreter command line options, type:: - - cd pypy/bin - python py.py --help - -As an example of using PyPy from the command line, you could type:: - - python py.py -c "from test import pystone; pystone.main(10)" - -Alternatively, as with regular Python, you can simply give a -script name on the command line:: - - python py.py ../../lib-python/modified-2.3.4/test/pystone.py 10 - -special PyPy features --------------------------- - -Interpreter-level console -+++++++++++++++++++++++++ - -There are a few extra features of the PyPy console: If you press - on the console you enter the interpreter-level console, a -usual CPython console. You can then access internal objects of PyPy -(e.g. the object space) and any variables you have created on the PyPy -prompt with the prefix ``w_``:: - - >>>> a = 123 - >>>> - *** Entering interpreter-level console *** - >>> w_a - W_IntObject(123) - -Note that the prompt of the interpreter-level console is only '>>>' since -it runs on CPython level. If you want to return to PyPy, press (under -Linux) or , (under Windows). - -You may be interested in reading more about the distinction between -`interpreter-level and app-level`_. - -.. _`interpreter-level and app-level`: architecture.html#interpreter-level - -.. _`trace example`: - -Tracing bytecode and operations on objects -++++++++++++++++++++++++++++++++++++++++++ - -You can use the trace object space to monitor the interpretation -of bytecodes in connection with object space operations. To enable -it, set ``__pytrace__=1`` on the interactive PyPy console:: - - >>>> __pytrace__ = 1 - Tracing enabled - >>>> a = 1 + 2 - |- <<<< enter a = 1 + 2 @ 1 >>>> - |- 0 LOAD_CONST 0 (W_IntObject(1)) - |- 3 LOAD_CONST 1 (W_IntObject(2)) - |- 6 BINARY_ADD - |- add(W_IntObject(1), W_IntObject(2)) -> W_IntObject(3) - |- 7 STORE_NAME 0 (a) - |- setitem(W_DictObject([ - |-10 LOAD_CONST 2 () - |-13 RETURN_VALUE - |- <<<< leave a = 1 + 2 @ 1 >>>> - - -lazily computed objects -+++++++++++++++++++++++ - -One of the original features provided by PyPy is the "thunk" -object space, providing lazily-computed objects in a fully -transparent manner:: - - cd pypy/bin - python py.py -o 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 100 lines of code. - -Running the tests -+++++++++++++++++ - -The PyPy project uses test-driven-development. Right now, there are -a couple of different categories of tests which you can run. -To run all the unit tests:: - - cd pypy - python test_all.py - -Alternatively, you may run subtests by going to the correct subdirectory -and running them individually:: - - python test_all.py module/test/test_builtin.py - -``test_all.py`` is actually just a synonym for `py.test`_ which is -our external testing tool. If you have installed that you -can as well just issue ``py.test DIRECTORY_OR_FILE`` in order -to perform test runs or simply start it without arguments to -run all tests below the current directory. - -Finally, there are the CPython regression tests which you can -run like this:: - - cd lib-python/2.3.4/test - python ../../../pypy/test_all.py -E - -or if you have `installed py.test`_ then you simply say:: - - py.test -E - -from the lib-python-2.3.4/test directory. - -.. _`installed py.test`: http://codespeak.net/py/current/doc/getting-started.html - -Demos -+++++ - -The `demo/`_ directory contains examples of various aspects of PyPy, -ranging from running regular Python programs (that we used as compliance goals) -over experimental distribution mechanisms to examples translating -sufficiently static programs into low level code. - -.. _`try out the translator`: - -Trying out the translator -------------------------- - -The translator is a tool based on the PyPy interpreter which can translate -sufficiently static Python programs into low-level code. To be able to use it -you need to: - - * Download and install `Dot Graphviz`_. - - * Download and install Pygame_ if you do not already have it. - -To start the interactive translator do:: - - cd pypy/bin - python translator.py - -Test snippets of translatable code are provided in the file -``pypy/translator/test/snippet.py``, which is imported under the name -``test``. For example:: - - >>> t = Translator(test.is_perfect_number) - >>> t.view() - -.. >>> from pypy.translator.translator import Translator -.. >>> from pypy.translator.test import snippet as test - - -trying out the type annotator -+++++++++++++++++++++++++++++ - -We have a type annotator that can completely infer types for functions like -``is_perfect_number`` (as well as for much larger examples):: - - >>> a = t.annotate([int]) - >>> t.view() - -Move the mouse over variable names (in red) to see their inferred types. To -perform simplifications based on the annotation you can do:: - - >>> a.simplify() - - -translating the flow graph to C code -++++++++++++++++++++++++++++++++++++ - -The graph can be turned into C code:: - - >>> t.specialize() - >>> f = t.ccompile() - -The first command replaces operations with variables of types that are -avaiable in C (e.g. int) with low level versions. This can be ommited if no -annotation (see last subsection) has been performed. - - -translating the flow graph to LLVM code -+++++++++++++++++++++++++++++++++++++++ - -If you feel adventureous (and have `LLVM installed`_ and on your path) you can -also try to compile the graph with LLVM. This is still quite experimental -and only works with some functions: One of the most visible restriction is -that return type of the entry function has to be and int, float or bool. To -try it do:: - - >>> print t.llvm() - >>> f = t.llvmcompile(optimize=True) - >>> f(28) - 1 - -This works only with fully annotated graphs. - -a slightly larger example -+++++++++++++++++++++++++ - -There is a small-to-medium demo showing the translator and the annotator:: - - cd demo - python bpnn.py - -This causes ``bpnn.py`` to display itself as a call graph and class -hierarchy. Clicking on functions shows the flow graph of the particular -function. Clicking on a class shows the attributes of its instances. All -this information (call graph, local variables' types, attributes of -instances) is computed by the annotator. - -As soon as you close the PyGame window, the function is turned into C code, -compiled and executed. - -translating the PyPy interpreter -++++++++++++++++++++++++++++++++ - -Not for the faint of heart nor the owner of a very old machine: you can -run the annotator over the whole PyPy interpreter itself. This is the -largest and ultimate example of source that our annotator can (very -successfully!) process:: - - cd pypy/translator/goal - python translate_pypy.py -no-t -no-c - -Moving around is difficult because of the sheer size of the result. -For this reason, the debugger prompt you get at the end has been -enhanced with commands to facilitate locating functions and classes. -Type ``help graphs`` for a list of the new commands. Help is also -available on each of these new commands. - -The ``translate_pypy`` script itself takes a number of options controlling -what to translate and how. See ``translate_pypy.py -h``. Try out:: - - cd pypy/translator/goal - python translate_pypy.py targetrpystone - -or a simplified, scaled-down version:: - - python translate_pypy.py targetrpystone2 - - -.. _`start reading sources`: - -Where to start reading the sources ----------------------------------- - -PyPy is made from parts that are relatively independent from each other. -You should start looking at the part that attracts you most (all parts are -relative to the PyPy toplevel directory). You may look at our `directory reference`_ -or start off at one of the following points: - -* `pypy/interpreter`_ contains the basic interpreter: bytecode dispatcher - in pyopcode.py_, frame and code objects in eval.py_ and pyframe.py_, - function objects and argument passing in function.py_ and argument.py_, - the object space interface definition in baseobjspace.py_, modules in - module.py_ and mixedmodule.py_. Core types supporting the interpreter are - defined in typedef.py_. - -* `pypy/objspace/std`_ contains the `Standard object space`_. The main file - is objspace.py_. For each type, the files ``xxxtype.py`` and - ``xxxobject.py`` contain respectively the definition of the type and its - (default) implementation. - -* `pypy/objspace`_ contains a few other object spaces: the thunk_ - one, the trace_ one, the flow_ one. The latter is a relatively short piece - of code that builds the control flow graphs when the interpreter runs in it. - -* `pypy/translator`_ contains the code analysis and generation stuff. - Start reading from translator.py_, from which it should be easy to follow - the pieces of code involved in the various translation phases. - -* `pypy/annotation`_ contains the data model for the type annotation that - can be inferred about a graph. The graph "walker" that uses this is in - `pypy/translator/annrpython.py`_. - - -.. _optionaltool: - -Additional Tools for running (and hacking) PyPy ------------------------------------------------ - -We use some optional tools for developing PyPy. They are not required to run -the basic tests or to get an interactive PyPy prompt but they help to -understand and debug PyPy especially for the ongoing translation work. - -graphviz & pygame for flowgraph viewing (highly recommended) -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -graphviz and pygame are both neccessary if you -want to look at generated flowgraphs: - - graphviz: http://www.research.att.com/sw/tools/graphviz/download.html - - pygame: http://www.pygame.org/download.shtml - -.. _`LLVM installed`: - -LLVM -+++++ - -LLVM is used by the optional `PyPy/LLVM backend`_ to generate -processor indepdendant machine level code for the `low level -virtual machine`_. LLVM can be quite annoying to install: you -need a fairly recent version of GCC to compile it and there -can be severe problems under windows. **NOTE: To use the LLVM -backend of PyPy you don't need the GCC front end of LLVM, only -LLVM itself**. Here are detailed instructions on how to -install: - - http://llvm.cs.uiuc.edu/docs/GettingStarted.html - -If you run into problems with the installation the `LLVM -mailing list`_ is very helpful and friendly. Note also that -the PyPy LLVM backend was developed using LLVM 1.4 but it -seems to work with LLVM 1.5. Nobody ever tried an older -version. - -CLISP -+++++++ - -The CLISP backend is optional and not quite uptodate with the rest of -PyPy. Still there are a few examples you can try our backend out on. -Here is a link to a LISP implementation that should basically work: - - http://clisp.cons.org/ - - -.. _`py.test`: - -py.test and the py lib -+++++++++++++++++++++++ - -The `py library`_ is used for supporting PyPy development and -running our tests against code and documentation as well as -compliancy tests. You don't need to install the py library because -it ships with PyPy and `pypy/test_all.py`_ is an alias for ``py.test`` -but if you want to have the ``py.test`` tool generally in your -path, you might like to visit: - - http://codespeak.net/py/current/doc/getting-started.html - - - -Getting involved -================================== - -PyPy employs an open development process. You are invited -to join our `pypy-dev mailing list`_ or look at the other -`contact possibilities`_. We are also doing coding Sprints -which are separatedly announced and often happen around Python -conferences such as EuroPython or Pycon. - -.. _`pypy-dev mailing list`: http://codespeak.net/mailman/listinfo/pypy-dev -.. _`contact possibilities`: http://codespeak.net/pypy/index.cgi?contact - -.. _`py library`: http://codespeak.net/py -.. _`PyPy/LLVM backend`: translation.html#llvm -.. _`low level virtual machine`: http://llvm.cs.uiuc.edu/ -.. _`how to install LLVM`: http://llvm.cs.uiuc.edu/docs/GettingStarted.html -.. _`LLVM mailing list`: http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev - - -.. _Dot Graphviz: http://www.research.att.com/sw/tools/graphviz/ -.. _Pygame: http://www.pygame.org/ -.. _pyopcode.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/pyopcode.py -.. _eval.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/eval.py -.. _pyframe.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/pyframe.py -.. _function.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/function.py -.. _argument.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/argument.py -.. _baseobjspace.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/baseobjspace.py -.. _module.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/module.py -.. _mixedmodule.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/mixedmodule.py -.. _typedef.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/typedef.py -.. _Standard object space: http://codespeak.net/pypy/index.cgi?doc/stdobjspace.html -.. _objspace.py: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/objspace.py -.. _thunk: http://codespeak.net/svn/pypy/dist/pypy/objspace/thunk.py -.. _trace: http://codespeak.net/svn/pypy/dist/pypy/objspace/trace.py -.. _flow: http://codespeak.net/svn/pypy/dist/pypy/objspace/flow/ -.. _translator.py: http://codespeak.net/svn/pypy/dist/pypy/translator/translator.py -.. _mailing lists: http://codespeak.net/pypy/index.cgi?lists -.. _documentation: index.html -.. _wiki: http://codespeak.net/moin/pypy/moin.cgi/FrontPage?action=show -.. _unit tests: http://codespeak.net/pypy/index.cgi?doc/testdesign.html -.. _bug reports: https://codespeak.net/issue/pypy-dev/ - -.. _`directory reference`: index.html#directory-reference - -.. include:: _ref.txt Modified: pypy/branch/dist-newdoc/pypy/documentation/index.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/index.txt (original) +++ pypy/branch/dist-newdoc/pypy/documentation/index.txt Mon Aug 22 16:49:59 2005 @@ -36,7 +36,7 @@ .. _`coding guide`: coding-guide.html .. _`architecture`: architecture.html .. _`revision report`: http://codespeak.net/pypy/rev/current -.. _`getting started`: getting_started.html +.. _`getting started`: getting-started.html .. _`theory`: theory.html .. _`bytecode interpreter`: interpreter.html Modified: pypy/branch/dist-newdoc/pypy/documentation/news.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/news.txt (original) +++ pypy/branch/dist-newdoc/pypy/documentation/news.txt Mon Aug 22 16:49:59 2005 @@ -7,7 +7,7 @@ nonsense, isn't it? `more...`_ .. _Python: http://www.python.org/doc/current/ref/ref.html -.. _`more...`: ../architecture.html#mission-statement +.. _`more...`: architecture.html#mission-statement Next PyPy Sprint in Heidelberg 22nd-29th August 2005 ====================================================== @@ -67,8 +67,8 @@ .. _`pypy-dev`: http://codespeak.net/mailman/listinfo/pypy-dev .. _EuroPython: http://europython.org -.. _`translation`: ../translation.html -.. _`sprint announcement`: EP2005-announcement.html +.. _`translation`: translation.html +.. _`sprint announcement`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/EP2005-announcement.html .. _`list of people coming`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/EP2005-people.html First PyPy release! Modified: pypy/branch/dist-newdoc/pypy/documentation/objspace.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/objspace.txt (original) +++ pypy/branch/dist-newdoc/pypy/documentation/objspace.txt Mon Aug 22 16:49:59 2005 @@ -243,7 +243,7 @@ A number of options for configuration is here in `traceconfig.py`_. -.. _`found here` : getting_started.html#tracing-bytecode-and-operations-on-objects +.. _`found here` : getting-started.html#tracing-bytecode-and-operations-on-objects .. _`Abstract Interpretation`: theory.html#abstract-interpretation .. _`traceconfig.py`: http://codespeak.net/svn/pypy/dist/pypy/tool/traceconfig.py Modified: pypy/branch/dist-newdoc/pypy/documentation/redirections ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/redirections (original) +++ pypy/branch/dist-newdoc/pypy/documentation/redirections Mon Aug 22 16:49:59 2005 @@ -27,5 +27,7 @@ 'coding-style.html' : 'coding-guide.html', 'controlflow.html' : 'objspace.html#the-flow-model', + + 'getting_started.html' : 'getting-started.html', } Modified: pypy/branch/dist-newdoc/pypy/documentation/release-0.6.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/release-0.6.txt (original) +++ pypy/branch/dist-newdoc/pypy/documentation/release-0.6.txt Mon Aug 22 16:49:59 2005 @@ -9,7 +9,7 @@ What it is and where to start ----------------------------- -Getting started: http://codespeak.net/pypy/index.cgi?doc/getting_started.html +Getting started: http://codespeak.net/pypy/index.cgi?doc/getting-started.html PyPy Documentation: http://codespeak.net/pypy/index.cgi?doc Modified: pypy/branch/dist-newdoc/pypy/documentation/translation.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/translation.txt (original) +++ pypy/branch/dist-newdoc/pypy/documentation/translation.txt Mon Aug 22 16:49:59 2005 @@ -51,7 +51,7 @@ .. _`SSA`: http://en.wikipedia.org/wiki/Static_single_assignment_form .. _`translator.py`: http://codespeak.net/svn/pypy/dist/pypy/translator/translator.py -.. _`play around`: getting_started.html#trying-out-the-translator +.. _`play around`: getting-started.html#trying-out-the-translator .. _`Flow Object Space`: objspace.html#the-flow-object-space .. _`control flow graph`: objspace.html#the-flow-model .. _`Common Lisp`: http://codespeak.net/svn/pypy/dist/pypy/translator/gencl.py From ale at codespeak.net Mon Aug 22 16:53:10 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 22 Aug 2005 16:53:10 +0200 (CEST) Subject: [pypy-svn] r16212 - pypy/dist/pypy/module/_codecs Message-ID: <20050822145310.0D4B127B43@code1.codespeak.net> Author: ale Date: Mon Aug 22 16:53:09 2005 New Revision: 16212 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: Corrected a misunderstanding in utf-16 decode Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Mon Aug 22 16:53:09 2005 @@ -199,9 +199,9 @@ def utf_16_decode( data,errors='strict',final=None): """None """ - res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors) + res,consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors) res = ''.join(res) - return res, len(res) + return res, consume def unicode_escape_decode( data,errors='strict'): """None @@ -287,9 +287,9 @@ byteorder = 'little' else: byteorder = 'big' - res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,byteorder) + res,consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,byteorder) res = ''.join(res) - return res, len(res), byteorder + return res, consumed, byteorder # XXX needs error messages when the input is invalid def escape_decode(data,errors='strict'): @@ -416,16 +416,16 @@ def utf_16_le_decode( data,errors='strict',byteorder=0, final = 0): """None """ - res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little') - res = ''.join(res) - return res, len(res) + res,consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little') + res = u''.join(res) + return res, consumed def utf_16_be_decode( data,errors='strict',byteorder=0, final = 0): """None """ - res = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big') - res = ''.join(res) - return res, len(res) + res, consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big') + res = u''.join(res) + return res, consumed def strict_errors(exc): if isinstance(exc,Exception): @@ -932,7 +932,7 @@ errmsg = "truncated data" startinpos = q endinpos = len(s) - unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) # /* The remaining input chars are ignored if the callback ## chooses to skip the input */ @@ -948,7 +948,7 @@ errmsg = "unexpected end of data" startinpos = q-2 endinpos = len(s) - unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) if (0xD800 <= ch and ch <= 0xDBFF): ch2 = (ord(s[q+ihi]) << 8) | ord(s[q+ilo]) @@ -967,14 +967,14 @@ errmsg = "illegal UTF-16 surrogate" startinpos = q-4 endinpos = startinpos+2 - unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) errmsg = "illegal encoding" startinpos = q-2 endinpos = startinpos+2 - unicode_call_errorhandler(errors,'utf-16',errmsg,startinpos,endinpos,True) + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) - return p + return p,q # moved out of local scope, especially because it didn't # have any nested variables. From hpk at codespeak.net Mon Aug 22 16:56:17 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 16:56:17 +0200 (CEST) Subject: [pypy-svn] r16214 - pypy/branch/dist-newdoc/pypy/documentation Message-ID: <20050822145617.406FB27B3F@code1.codespeak.net> Author: hpk Date: Mon Aug 22 16:56:07 2005 New Revision: 16214 Modified: pypy/branch/dist-newdoc/pypy/documentation/navlist pypy/branch/dist-newdoc/pypy/documentation/redirections pypy/branch/dist-newdoc/pypy/documentation/test_redirections.py Log: fix redirection information to follow the current paths Modified: pypy/branch/dist-newdoc/pypy/documentation/navlist ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/navlist (original) +++ pypy/branch/dist-newdoc/pypy/documentation/navlist Mon Aug 22 16:56:07 2005 @@ -1,6 +1,6 @@ [ 'architecture.html', - 'getting_started.html', + 'getting-started.html', 'coding-guide.html', 'objspace.html', 'translation.html', Modified: pypy/branch/dist-newdoc/pypy/documentation/redirections ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/redirections (original) +++ pypy/branch/dist-newdoc/pypy/documentation/redirections Mon Aug 22 16:56:07 2005 @@ -10,8 +10,8 @@ 'abstractobjspace.html' : 'theory.html#abstract-interpretation', 'multimethod.html' : 'theory.html#multimethods', - 'howtopypy.html' : 'getting_started.html#howtopypy', - 'howtosvn.html' : 'getting_started.html#howtosvn', + 'howtopypy.html' : 'getting-started.html#howtopypy', + 'howtosvn.html' : 'getting-started.html#howtosvn', 'checking_ReST.html' : 'coding-guide.html#pypy-documentation', 'optionaltools.html' : 'coding-guide.html#optionaltool', @@ -29,5 +29,7 @@ 'controlflow.html' : 'objspace.html#the-flow-model', 'getting_started.html' : 'getting-started.html', + 'getting_started.html#howtopypy' : 'getting-started.html#howtopypy', + 'getting_started.html#howtosvn' : 'getting-started.html#howtosvn', } Modified: pypy/branch/dist-newdoc/pypy/documentation/test_redirections.py ============================================================================== --- pypy/branch/dist-newdoc/pypy/documentation/test_redirections.py (original) +++ pypy/branch/dist-newdoc/pypy/documentation/test_redirections.py Mon Aug 22 16:56:07 2005 @@ -3,6 +3,7 @@ redir = py.magic.autopath().dirpath('redirections') def checkexist(path): + print "checking", path assert path.new(ext='.txt').check(file=1) def test_eval(): From arigo at codespeak.net Mon Aug 22 16:56:17 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Aug 2005 16:56:17 +0200 (CEST) Subject: [pypy-svn] r16213 - in pypy/dist/pypy: module/thread/rpython translator/c translator/c/src translator/c/test Message-ID: <20050822145617.37ABE27B47@code1.codespeak.net> Author: arigo Date: Mon Aug 22 16:55:59 2005 New Revision: 16213 Added: pypy/dist/pypy/translator/c/src/g_prerequisite.h (contents, props changed) pypy/dist/pypy/translator/c/src/ll_thread.h (contents, props changed) pypy/dist/pypy/translator/c/src/thread.h (contents, props changed) pypy/dist/pypy/translator/c/src/thread_nt.h (contents, props changed) pypy/dist/pypy/translator/c/src/thread_pthread.h (contents, props changed) Modified: pypy/dist/pypy/module/thread/rpython/ll_thread.py pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/src/exception.h pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Starting the C back-end support for the 'thread' module. Supported so far: creating and destroying lock objects. * extends database.py/node.py with an ExtTypeOpaqueDefNode corresponding to the inlined Opaque field. * struct RPyOpaque_ThreadLock must be declared early, because it is the type of the above field. Added a g_prerequisite.h that is included before the struct definitions generated by genc. * thread support is split in several header files: - thread.h selects between APIs depending on platform - thread_pthread.h for pthread (Linux & co.) - thread_nt.h for NT (not tested!! copied from CPython) - ll_thread.h included later (see comments in that file) Modified: pypy/dist/pypy/module/thread/rpython/ll_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/ll_thread.py (original) +++ pypy/dist/pypy/module/thread/rpython/ll_thread.py Mon Aug 22 16:55:59 2005 @@ -26,27 +26,27 @@ ll_thread_get_ident.suggested_primitive = True -def newlock(opaqueptr): +def ll_newlock(opaqueptr): init_opaque_object(opaqueptr, thread.allocate_lock()) -newlock.suggested_primitive = True +ll_newlock.suggested_primitive = True -def acquirelock(opaqueptr, waitflag): +def ll_acquirelock(opaqueptr, waitflag): lock = from_opaque_object(opaqueptr) return lock.acquire(waitflag) -acquirelock.suggested_primitive = True +ll_acquirelock.suggested_primitive = True -def releaselock(opaqueptr): +def ll_releaselock(opaqueptr): lock = from_opaque_object(opaqueptr) lock.release() -releaselock.suggested_primitive = True +ll_releaselock.suggested_primitive = True def ll_thread_allocate_lock(): lockcontainer = malloc(LOCKCONTAINERTYPE) - newlock(lockcontainer.obj) + ll_newlock(lockcontainer.obj) return lockcontainer def ll_thread_acquire_lock(lockcontainer, waitflag): - return acquirelock(lockcontainer.obj, waitflag) + return ll_acquirelock(lockcontainer.obj, waitflag) def ll_thread_release_lock(lockcontainer): - releaselock(lockcontainer.obj) + ll_releaselock(lockcontainer.obj) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Mon Aug 22 16:55:59 2005 @@ -1,11 +1,11 @@ -from pypy.rpython.lltype import Primitive, Ptr, typeOf +from pypy.rpython.lltype import Primitive, Ptr, typeOf, RuntimeTypeInfo from pypy.rpython.lltype import Struct, Array, FuncType, PyObject, Void from pypy.rpython.lltype import ContainerType, pyobjectptr, OpaqueType, GcStruct from pypy.objspace.flow.model import Constant from pypy.translator.c.primitive import PrimitiveName, PrimitiveType from pypy.translator.c.primitive import PrimitiveErrorValue from pypy.translator.c.node import StructDefNode, ArrayDefNode -from pypy.translator.c.node import ContainerNodeClass +from pypy.translator.c.node import ContainerNodeClass, ExtTypeOpaqueDefNode from pypy.translator.c.support import cdecl, CNameManager, ErrorValue from pypy.translator.c.pyobj import PyObjMaker @@ -37,6 +37,8 @@ node = StructDefNode(self, T, varlength) elif isinstance(T, Array): node = ArrayDefNode(self, T, varlength) + elif isinstance(T, OpaqueType) and hasattr(T, '_exttypeinfo'): + node = ExtTypeOpaqueDefNode(self, T) else: raise Exception("don't know about %r" % (T,)) self.structdefnodes[key] = node @@ -70,8 +72,14 @@ argtypes = ', '.join(argtypes) or 'void' return resulttype.replace('@', '(@)(%s)' % argtypes) elif isinstance(T, OpaqueType): - if T.tag == 'RuntimeTypeInfo': + if T == RuntimeTypeInfo: return 'void (@)(void *)' # void dealloc_xx(struct xx *) + elif hasattr(T, '_exttypeinfo'): + # for external types (pypy.rpython.extfunctable.declaretype()) + node = self.gettypedefnode(T, varlength=varlength) + if who_asks is not None: + who_asks.dependencies[node] = True + return 'struct %s @' % node.name else: raise Exception("don't know about opaque type %r" % (T,)) else: Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Mon Aug 22 16:55:59 2005 @@ -5,6 +5,7 @@ from pypy.rpython.rstr import STR from pypy.rpython import rlist from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod +from pypy.module.thread.rpython import ll_thread # table of functions hand-written in src/ll_*.h @@ -35,6 +36,7 @@ 'LL_strtod_parts_to_float', ll_strtod.ll_strtod_formatd: 'LL_strtod_formatd', + ll_thread.ll_newlock: 'LL_thread_newlock', } #______________________________________________________ @@ -113,7 +115,10 @@ lltype.pyobjectptr(pyexccls)) # strange naming here because the macro name must be # a substring of PyExc_%s - yield ('RPyExc_%s' % pyexccls.__name__, exc_llvalue) + name = pyexccls.__name__ + if pyexccls.__module__ != 'exceptions': + name = '%s_%s' % (pyexccls.__module__, name) + yield ('RPyExc_%s' % name, exc_llvalue) def predeclare_all(db, rtyper): Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Mon Aug 22 16:55:59 2005 @@ -200,7 +200,7 @@ # for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) - print >> f, '#include "Python.h"' + print >> f, '#include "src/g_prerequisite.h"' includes = {} for node in database.globalcontainers(): for include in node.includes: Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Mon Aug 22 16:55:59 2005 @@ -131,7 +131,7 @@ if self.static_deallocator: yield 'void %s(struct %s *p) {' % (self.static_deallocator, self.name) - for line in self.deallocator_lines('p->'): + for line in self.deallocator_lines('(*p)'): yield '\t' + line yield '\tOP_FREE(p);' yield '}' @@ -154,7 +154,7 @@ FIELD_T = self.c_struct_field_type(name) cname = self.c_struct_field_name(name) for line in generic_dealloc(self.db, - '%s%s' % (prefix, cname), + '%s.%s' % (prefix, cname), FIELD_T): yield line @@ -227,7 +227,7 @@ elif phase == 2 and self.deallocator: yield 'void %s(struct %s *a) {' % (self.deallocator, self.name) - for line in self.deallocator_lines('a->'): + for line in self.deallocator_lines('(*a)'): yield '\t' + line yield '\tOP_FREE(a);' yield '}' @@ -244,12 +244,12 @@ body = list(generic_dealloc(self.db, '(*%s)' % varname, ARRAY.OF)) if body: yield '{' - yield '\t%s = %sitems;' % (cdecl(self.itemtypename, '*' + varname), - prefix) - yield '\t%s = %s + %slength;' % (cdecl(self.itemtypename, - '*%s_end' % varname), - varname, - prefix) + yield '\t%s = %s.items;' % (cdecl(self.itemtypename, '*' + varname), + prefix) + yield '\t%s = %s + %s.length;' % (cdecl(self.itemtypename, + '*%s_end' % varname), + varname, + prefix) yield '\twhile (%s != %s_end) {' % (varname, varname) for line in body: yield '\t\t' + line @@ -268,6 +268,25 @@ yield '-1' +class ExtTypeOpaqueDefNode: + "For OpaqueTypes created by pypy.rpython.extfunctable.ExtTypeInfo." + + def __init__(self, db, T): + self.db = db + self.T = T + self.dependencies = {} + self.name = 'RPyOpaque_%s' % (T.tag,) + + def setup(self): + pass + + def deallocator_lines(self, prefix): + yield 'RPyOpaqueDealloc_%s(&(%s));' % (self.T.tag, prefix) + + def definition(self, phase): + return [] + + def generic_dealloc(db, expr, T): if isinstance(T, Ptr) and T._needsgc(): line = db.cdecrefstmt(expr, T) @@ -275,7 +294,7 @@ yield line elif isinstance(T, ContainerType): defnode = db.gettypedefnode(T) - for line in defnode.deallocator_lines('%s.' % expr): + for line in defnode.deallocator_lines(expr): yield line # ____________________________________________________________ Modified: pypy/dist/pypy/translator/c/src/exception.h ============================================================================== --- pypy/dist/pypy/translator/c/src/exception.h (original) +++ pypy/dist/pypy/translator/c/src/exception.h Mon Aug 22 16:55:59 2005 @@ -97,7 +97,7 @@ #define RPyConvertExceptionToCPython(vanishing) vanishing = NULL #define RPyRaiseSimpleException(exc, msg) \ - PyErr_SetString(exc, msg) /* pun */ + PyErr_SetString(exc, msg) /******************************************************************/ #endif /* HAVE_RTYPER */ Modified: pypy/dist/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_include.h (original) +++ pypy/dist/pypy/translator/c/src/g_include.h Mon Aug 22 16:55:59 2005 @@ -36,6 +36,7 @@ # include "src/ll_time.h" # include "src/ll_math.h" # include "src/ll_strtod.h" +# include "src/ll_thread.h" #endif #ifdef PYPY_STANDALONE Added: pypy/dist/pypy/translator/c/src/g_prerequisite.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/g_prerequisite.h Mon Aug 22 16:55:59 2005 @@ -0,0 +1,8 @@ + +/**************************************************************/ +/*** this is included before any code produced by genc.py ***/ + +#include "Python.h" + +#include "thread.h" /* needs to be included early to define the + struct RPyOpaque_ThreadLock */ Added: pypy/dist/pypy/translator/c/src/ll_thread.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/ll_thread.h Mon Aug 22 16:55:59 2005 @@ -0,0 +1,17 @@ +/************************************************************/ + /*** C header subsection: OS-level threads ***/ + + +/* The core comes from thread.h, which is included from g_prerequisite.h. + The functions below are declared later (from g_include.h). */ + +/* this cannot be moved to thread_*.h because: + * - RPyRaiseSimpleException and PyExc_thread_error are not declared yet + * - the macro redefining LL_thread_newlock (produced by genc) is not defined + * yet + */ +void LL_thread_newlock(struct RPyOpaque_ThreadLock *lock) +{ + if (!RPyThreadLockInit(lock)) + RPyRaiseSimpleException(PyExc_thread_error, "out of resources"); +} Added: pypy/dist/pypy/translator/c/src/thread.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/thread.h Mon Aug 22 16:55:59 2005 @@ -0,0 +1,19 @@ + +/* #ifdef logic from CPython */ + +#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 +#include "thread_pthread.h" +#endif + +#ifdef NT_THREADS +#include "thread_nt.h" +#endif Added: pypy/dist/pypy/translator/c/src/thread_nt.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/thread_nt.h Mon Aug 22 16:55:59 2005 @@ -0,0 +1,125 @@ +/* Copy-and-pasted from CPython */ + +/* This code implemented by Dag.Gruneau at elsa.preseco.comm.se */ +/* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch at iso.ru */ +/* Eliminated some memory leaks, gsw at agere.com */ + +#include +#include +#include + +typedef struct RPyOpaque_ThreadLock { + LONG owned ; + DWORD thread_id ; + HANDLE hevent ; +} NRMUTEX, *PNRMUTEX ; + +typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ; + +/* Sorry mate, but we haven't got InterlockedCompareExchange in Win95! */ +static PVOID WINAPI interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand) +{ + static LONG spinlock = 0 ; + PVOID result ; + DWORD dwSleep = 0; + + /* Acqire spinlock (yielding control to other threads if cant aquire for the moment) */ + while(InterlockedExchange(&spinlock, 1)) + { + // Using Sleep(0) can cause a priority inversion. + // Sleep(0) only yields the processor if there's + // another thread of the same priority that's + // ready to run. If a high-priority thread is + // trying to acquire the lock, which is held by + // a low-priority thread, then the low-priority + // thread may never get scheduled and hence never + // free the lock. NT attempts to avoid priority + // inversions by temporarily boosting the priority + // of low-priority runnable threads, but the problem + // can still occur if there's a medium-priority + // thread that's always runnable. If Sleep(1) is used, + // then the thread unconditionally yields the CPU. We + // only do this for the second and subsequent even + // iterations, since a millisecond is a long time to wait + // if the thread can be scheduled in again sooner + // (~100,000 instructions). + // Avoid priority inversion: 0, 1, 0, 1,... + Sleep(dwSleep); + dwSleep = !dwSleep; + } + result = *dest ; + if (result == comperand) + *dest = exc ; + /* Release spinlock */ + spinlock = 0 ; + return result ; +} ; + +static interlocked_cmp_xchg_t *ixchg ; +BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex) +{ + if (!ixchg) + { + /* Sorely, Win95 has no InterlockedCompareExchange API (Win98 has), so we have to use emulation */ + HANDLE kernel = GetModuleHandle("kernel32.dll") ; + if (!kernel || (ixchg = (interlocked_cmp_xchg_t *)GetProcAddress(kernel, "InterlockedCompareExchange")) == NULL) + ixchg = interlocked_cmp_xchg ; + } + + mutex->owned = -1 ; /* No threads have entered NonRecursiveMutex */ + mutex->thread_id = 0 ; + mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ; + return mutex->hevent != NULL ; /* TRUE if the mutex is created */ +} + +#ifdef InterlockedCompareExchange +#undef InterlockedCompareExchange +#endif +#define InterlockedCompareExchange(dest,exchange,comperand) (ixchg((dest), (exchange), (comperand))) + +VOID DeleteNonRecursiveMutex(PNRMUTEX mutex) +{ + /* No in-use check */ + CloseHandle(mutex->hevent) ; + mutex->hevent = NULL ; /* Just in case */ +} + +DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait) +{ + /* Assume that the thread waits successfully */ + DWORD ret ; + + /* InterlockedIncrement(&mutex->owned) == 0 means that no thread currently owns the mutex */ + if (!wait) + { + if (InterlockedCompareExchange((PVOID *)&mutex->owned, (PVOID)0, (PVOID)-1) != (PVOID)-1) + return WAIT_TIMEOUT ; + ret = WAIT_OBJECT_0 ; + } + else + ret = InterlockedIncrement(&mutex->owned) ? + /* Some thread owns the mutex, let's wait... */ + WaitForSingleObject(mutex->hevent, INFINITE) : WAIT_OBJECT_0 ; + + mutex->thread_id = GetCurrentThreadId() ; /* We own it */ + return ret ; +} + +BOOL LeaveNonRecursiveMutex(PNRMUTEX mutex) +{ + /* We don't own the mutex */ + mutex->thread_id = 0 ; + return + InterlockedDecrement(&mutex->owned) < 0 || + SetEvent(mutex->hevent) ; /* Other threads are waiting, wake one on them up */ +} + +/************************************************************/ + +#define RPyThreadLockInit(lock) InitializeNonRecursiveMutex(lock) + +void RPyOpaqueDealloc_ThreadLock(struct RPyOpaque_ThreadLock *lock) +{ + if (lock->hevent != NULL) + DeleteNonRecursiveMutex(lock); +} Added: pypy/dist/pypy/translator/c/src/thread_pthread.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/thread_pthread.h Mon Aug 22 16:55:59 2005 @@ -0,0 +1,129 @@ + +/* Posix threads interface (from CPython) */ + +#include +#include + +/* The POSIX spec says that implementations supporting the sem_* + family of functions must indicate this by defining + _POSIX_SEMAPHORES. */ +#ifdef _POSIX_SEMAPHORES +/* On FreeBSD 4.x, _POSIX_SEMAPHORES is defined empty, so + we need to add 0 to make it work there as well. */ +#if (_POSIX_SEMAPHORES+0) == -1 +#define HAVE_BROKEN_POSIX_SEMAPHORES +#else +#include +#endif +#endif + +#if !defined(pthread_attr_default) +# define pthread_attr_default ((pthread_attr_t *)NULL) +#endif +#if !defined(pthread_mutexattr_default) +# define pthread_mutexattr_default ((pthread_mutexattr_t *)NULL) +#endif +#if !defined(pthread_condattr_default) +# define pthread_condattr_default ((pthread_condattr_t *)NULL) +#endif + +/* Whether or not to use semaphores directly rather than emulating them with + * mutexes and condition variables: + */ +#if defined(_POSIX_SEMAPHORES) && !defined(HAVE_BROKEN_POSIX_SEMAPHORES) +# define USE_SEMAPHORES +#else +# undef USE_SEMAPHORES +#endif + + +#define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; } + + +/************************************************************/ +#ifdef USE_SEMAPHORES +/************************************************************/ + +#include + +struct RPyOpaque_ThreadLock { + sem_t sem; + int initialized; +}; + +int RPyThreadLockInit(struct RPyOpaque_ThreadLock *lock) +{ + int status, error = 0; + lock->initialized = 0; + status = sem_init(&lock->sem, 0, 1); + CHECK_STATUS("sem_init"); + if (error) + return 0; + lock->initialized = 1; + return 1; +} + +void RPyOpaqueDealloc_ThreadLock(struct RPyOpaque_ThreadLock *lock) +{ + int status, error = 0; + if (lock->initialized) { + status = sem_destroy(&lock->sem); + CHECK_STATUS("sem_destroy"); + /* 'error' is ignored; + CHECK_STATUS already printed an error message */ + } +} + +/************************************************************/ +#else /* no semaphores */ +/************************************************************/ + +/* A pthread mutex isn't sufficient to model the Python lock type + (see explanations in CPython's Python/thread_pthread.h */ +struct RPyOpaque_ThreadLock { + char locked; /* 0=unlocked, 1=locked */ + char initialized; + /* a pair to handle an acquire of a locked lock */ + pthread_cond_t lock_released; + pthread_mutex_t mut; +}; + +int RPyThreadLockInit(struct RPyOpaque_ThreadLock *lock) +{ + int status, error = 0; + + lock->initialized = 0; + lock->locked = 0; + + status = pthread_mutex_init(&lock->mut, + pthread_mutexattr_default); + CHECK_STATUS("pthread_mutex_init"); + + status = pthread_cond_init(&lock->lock_released, + pthread_condattr_default); + CHECK_STATUS("pthread_cond_init"); + + if (error) + return 0; + lock->initialized = 1; + return 1; +} + +void RPyOpaqueDealloc_ThreadLock(struct RPyOpaque_ThreadLock *lock) +{ + int status, error = 0; + if (lock->initialized) { + status = pthread_mutex_destroy(&lock->mut); + CHECK_STATUS("pthread_mutex_destroy"); + + status = pthread_cond_destroy(&lock->lock_released); + CHECK_STATUS("pthread_cond_destroy"); + + /* 'error' is ignored; + CHECK_STATUS already printed an error message */ + } +} + +/************************************************************/ +#endif /* no semaphores */ +/************************************************************/ Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Mon Aug 22 16:55:59 2005 @@ -302,3 +302,18 @@ assert f(0.0) == "0.00" assert f(1.5) == "1.50" assert f(2.0) == "2.00" + +def test_lock(): + import thread + import pypy.module.thread.rpython.exttable # for declare()/declaretype() + def fn(): + l = thread.allocate_lock() + #ok1 = l.acquire(True) + #ok2 = l.acquire(False) + #l.release() + #ok3 = l.acquire(False) + #return ok1 and not ok2 and ok3 + return True + f = compile(fn, []) + res = f() + assert res is True From ale at codespeak.net Mon Aug 22 17:11:08 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 22 Aug 2005 17:11:08 +0200 (CEST) Subject: [pypy-svn] r16215 - pypy/dist/pypy/module/_codecs Message-ID: <20050822151108.99A3C27B43@code1.codespeak.net> Author: ale Date: Mon Aug 22 17:11:04 2005 New Revision: 16215 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: typo Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Mon Aug 22 17:11:04 2005 @@ -201,7 +201,7 @@ """ res,consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors) res = ''.join(res) - return res, consume + return res, consumed def unicode_escape_decode( data,errors='strict'): """None From hpk at codespeak.net Mon Aug 22 17:29:26 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 17:29:26 +0200 (CEST) Subject: [pypy-svn] r16216 - in pypy/branch/dist-newdoc/pypy: doc documentation Message-ID: <20050822152926.993AA27B43@code1.codespeak.net> Author: hpk Date: Mon Aug 22 17:29:25 2005 New Revision: 16216 Added: pypy/branch/dist-newdoc/pypy/doc/ - copied from r16215, pypy/branch/dist-newdoc/pypy/documentation/ Removed: pypy/branch/dist-newdoc/pypy/documentation/ Log: rename documentation to 'doc' From arigo at codespeak.net Mon Aug 22 17:44:42 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Aug 2005 17:44:42 +0200 (CEST) Subject: [pypy-svn] r16217 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20050822154442.D99B527B3F@code1.codespeak.net> Author: arigo Date: Mon Aug 22 17:44:40 2005 New Revision: 16217 Modified: pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_thread.h pypy/dist/pypy/translator/c/src/thread_nt.h pypy/dist/pypy/translator/c/src/thread_pthread.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: (rxe, arigo) genc: acquire() and release() methods of locks. (thread_nt is still untested) Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Mon Aug 22 17:44:40 2005 @@ -36,7 +36,9 @@ 'LL_strtod_parts_to_float', ll_strtod.ll_strtod_formatd: 'LL_strtod_formatd', - ll_thread.ll_newlock: 'LL_thread_newlock', + ll_thread.ll_newlock: 'LL_thread_newlock', + ll_thread.ll_acquirelock: 'LL_thread_acquirelock', + ll_thread.ll_releaselock: 'LL_thread_releaselock', } #______________________________________________________ Modified: pypy/dist/pypy/translator/c/src/ll_thread.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_thread.h (original) +++ pypy/dist/pypy/translator/c/src/ll_thread.h Mon Aug 22 17:44:40 2005 @@ -15,3 +15,23 @@ if (!RPyThreadLockInit(lock)) RPyRaiseSimpleException(PyExc_thread_error, "out of resources"); } + +int LL_thread_acquirelock(struct RPyOpaque_ThreadLock *lock, int waitflag) +{ + return RPyThreadAcquireLock(lock, waitflag); +} + +void LL_thread_releaselock(struct RPyOpaque_ThreadLock *lock) +{ + /* XXX this code is only quasi-thread-safe because the GIL is held + across its whole execution! */ + + /* Sanity check: the lock must be locked */ + if (RPyThreadAcquireLock(lock, 0)) { + RPyThreadReleaseLock(lock); + RPyRaiseSimpleException(PyExc_thread_error, "bad lock"); + } + else { + RPyThreadReleaseLock(lock); + } +} Modified: pypy/dist/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/dist/pypy/translator/c/src/thread_nt.h (original) +++ pypy/dist/pypy/translator/c/src/thread_nt.h Mon Aug 22 17:44:40 2005 @@ -123,3 +123,20 @@ if (lock->hevent != NULL) DeleteNonRecursiveMutex(lock); } + +/* + * Return 1 on success if the lock was acquired + * + * and 0 if the lock was not acquired. This means a 0 is returned + * if the lock has already been acquired by this thread! + */ +int RPyThreadAcquireLock(struct RPyOpaque_ThreadLock *lock, int waitflag) +{ + return EnterNonRecursiveMutex(lock, (waitflag != 0 ? INFINITE : 0)) == WAIT_OBJECT_0; +} + +void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock) +{ + if (!LeaveNonRecursiveMutex(lock)) + /* XXX complain? */; +} Modified: pypy/dist/pypy/translator/c/src/thread_pthread.h ============================================================================== --- pypy/dist/pypy/translator/c/src/thread_pthread.h (original) +++ pypy/dist/pypy/translator/c/src/thread_pthread.h Mon Aug 22 17:44:40 2005 @@ -74,6 +74,50 @@ } } +/* + * As of February 2002, Cygwin thread implementations mistakenly report error + * codes in the return value of the sem_ calls (like the pthread_ functions). + * Correct implementations return -1 and put the code in errno. This supports + * either. + */ +static int +rpythread_fix_status(int status) +{ + return (status == -1) ? errno : status; +} + +int RPyThreadAcquireLock(struct RPyOpaque_ThreadLock *lock, int waitflag) +{ + int success; + sem_t *thelock = &lock->sem; + int status, error = 0; + + do { + if (waitflag) + status = rpythread_fix_status(sem_wait(thelock)); + else + status = rpythread_fix_status(sem_trywait(thelock)); + } while (status == EINTR); /* Retry if interrupted by a signal */ + + if (waitflag) { + CHECK_STATUS("sem_wait"); + } else if (status != EAGAIN) { + CHECK_STATUS("sem_trywait"); + } + + success = (status == 0) ? 1 : 0; + return success; +} + +void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock) +{ + sem_t *thelock = &lock->sem; + int status, error = 0; + + status = sem_post(thelock); + CHECK_STATUS("sem_post"); +} + /************************************************************/ #else /* no semaphores */ /************************************************************/ @@ -124,6 +168,52 @@ } } +int RPyThreadAcquireLock(struct RPyOpaque_ThreadLock *lock, int waitflag) +{ + int success; + int status, error = 0; + + status = pthread_mutex_lock( &lock->mut ); + CHECK_STATUS("pthread_mutex_lock[1]"); + success = lock->locked == 0; + + if ( !success && waitflag ) { + /* continue trying until we get the lock */ + + /* mut must be locked by me -- part of the condition + * protocol */ + while ( lock->locked ) { + status = pthread_cond_wait(&lock->lock_released, + &lock->mut); + CHECK_STATUS("pthread_cond_wait"); + } + success = 1; + } + if (success) lock->locked = 1; + status = pthread_mutex_unlock( &lock->mut ); + CHECK_STATUS("pthread_mutex_unlock[1]"); + + if (error) success = 0; + return success; +} + +void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock) +{ + int status, error = 0; + + status = pthread_mutex_lock( &lock->mut ); + CHECK_STATUS("pthread_mutex_lock[3]"); + + lock->locked = 0; + + status = pthread_mutex_unlock( &lock->mut ); + CHECK_STATUS("pthread_mutex_unlock[3]"); + + /* wake up someone (anyone, if any) waiting on the lock */ + status = pthread_cond_signal( &lock->lock_released ); + CHECK_STATUS("pthread_cond_signal"); +} + /************************************************************/ #endif /* no semaphores */ /************************************************************/ Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Mon Aug 22 17:44:40 2005 @@ -308,12 +308,16 @@ import pypy.module.thread.rpython.exttable # for declare()/declaretype() def fn(): l = thread.allocate_lock() - #ok1 = l.acquire(True) - #ok2 = l.acquire(False) - #l.release() - #ok3 = l.acquire(False) - #return ok1 and not ok2 and ok3 - return True + ok1 = l.acquire(True) + ok2 = l.acquire(False) + l.release() + ok2_and_a_half = False + try: + l.release() + except thread.error: + ok2_and_a_half = True + ok3 = l.acquire(False) + return ok1 and not ok2 and ok2_and_a_half and ok3 f = compile(fn, []) res = f() assert res is True From tismer at codespeak.net Mon Aug 22 18:46:44 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 22 Aug 2005 18:46:44 +0200 (CEST) Subject: [pypy-svn] r16221 - in pypy/dist/pypy/rpython: . module module/test Message-ID: <20050822164644.EEF1627B41@code1.codespeak.net> Author: tismer Date: Mon Aug 22 18:46:42 2005 New Revision: 16221 Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/rpython/module/test/test_ll_os.py Log: support for os.system this is rather simple to implement, and needed in order to fake the compiler from the executable. Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Mon Aug 22 18:46:42 2005 @@ -141,6 +141,7 @@ declare(os.ftruncate, noneannotation, 'll_os/ftruncate') declare(os.fstat , statannotation, 'll_os/fstat') declare(os.stat , statannotation, 'll_os/stat') +declare(os.system , int , 'll_os/system') declare(os.strerror , str , 'll_os/strerror') declare(os.path.exists, bool , 'll_os_path/exists') declare(os.path.isdir, bool , 'll_os_path/isdir') Modified: pypy/dist/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/module/ll_os.py Mon Aug 22 18:46:42 2005 @@ -113,3 +113,7 @@ def ll_os_strerror(errnum): return to_rstr(os.strerror(errnum)) ll_os_getcwd.suggested_primitive = True + +def ll_os_system(cmd): + return os.system(from_rstr(cmd)) +ll_os_system.suggested_primitive = True Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Mon Aug 22 18:46:42 2005 @@ -27,3 +27,10 @@ def test_strerror(): data = ll_os_strerror(2) assert from_rstr(data) == os.strerror(2) + +def test_system(): + arg = to_rstr('python -c "print 1+1" > x') + data = ll_os_system(arg) + assert data == 0 + assert file('x').read().strip() == '2' + os.unlink('x') From tismer at codespeak.net Mon Aug 22 18:49:11 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 22 Aug 2005 18:49:11 +0200 (CEST) Subject: [pypy-svn] r16222 - pypy/dist/pypy/rpython/module/test Message-ID: <20050822164911.6D46927B41@code1.codespeak.net> Author: tismer Date: Mon Aug 22 18:49:10 2005 New Revision: 16222 Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py Log: ok ok, using udir now :-) Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Mon Aug 22 18:49:10 2005 @@ -29,8 +29,9 @@ assert from_rstr(data) == os.strerror(2) def test_system(): - arg = to_rstr('python -c "print 1+1" > x') + filename = str(udir.join('test_system.txt')) + arg = to_rstr('python -c "print 1+1" > %s' % filename) data = ll_os_system(arg) assert data == 0 - assert file('x').read().strip() == '2' - os.unlink('x') + assert file(filename).read().strip() == '2' + os.unlink(filename) From hpk at codespeak.net Mon Aug 22 18:50:51 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 18:50:51 +0200 (CEST) Subject: [pypy-svn] r16223 - in pypy/branch/dist-newdoc/pypy/doc: . tool Message-ID: <20050822165051.315E427B41@code1.codespeak.net> Author: hpk Date: Mon Aug 22 18:50:50 2005 New Revision: 16223 Modified: pypy/branch/dist-newdoc/pypy/doc/_ref.txt pypy/branch/dist-newdoc/pypy/doc/coding-guide.txt pypy/branch/dist-newdoc/pypy/doc/index.txt pypy/branch/dist-newdoc/pypy/doc/svn-help.txt pypy/branch/dist-newdoc/pypy/doc/tool/makeref.py Log: - more steps towards referential integrity inside a verision of the documentation - get rid of non-ascii char in svn-help Modified: pypy/branch/dist-newdoc/pypy/doc/_ref.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/doc/_ref.txt (original) +++ pypy/branch/dist-newdoc/pypy/doc/_ref.txt Mon Aug 22 18:50:50 2005 @@ -1,54 +1,53 @@ -.. _`demo/`: http://codespeak.net/svn/pypy/dist/demo -.. _`lib-python/`: http://codespeak.net/svn/pypy/dist/lib-python -.. _`pypy/annotation`: -.. _`annotation/`: http://codespeak.net/svn/pypy/dist/pypy/annotation -.. _`annotation/binaryop.py`: http://codespeak.net/svn/pypy/dist/pypy/annotation/binaryop.py -.. _`documentation/`: http://codespeak.net/svn/pypy/dist/pypy/documentation -.. _`documentation/revreport/`: http://codespeak.net/svn/pypy/dist/pypy/documentation/revreport -.. _`documentation/website/`: http://codespeak.net/svn/pypy/dist/pypy/documentation/website -.. _`pypy/interpreter`: -.. _`interpreter/`: http://codespeak.net/svn/pypy/dist/pypy/interpreter -.. _`pypy/interpreter/argument.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/argument.py -.. _`pypy/interpreter/function.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/function.py -.. _`pypy/interpreter/gateway.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/gateway.py -.. _`pypy/interpreter/generator.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/generator.py -.. _`pypy/interpreter/mixedmodule.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/mixedmodule.py -.. _`pypy/interpreter/nestedscope.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/nestedscope.py -.. _`pypy/interpreter/pyopcode.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/pyopcode.py -.. _`pypy/interpreter/typedef.py`: http://codespeak.net/svn/pypy/dist/pypy/interpreter/typedef.py +.. _`demo/`: ../../demo +.. _`lib-python/`: ../../lib-python +.. _`annotation/`: +.. _`pypy/annotation`: ../../pypy/annotation +.. _`annotation/binaryop.py`: ../../pypy/annotation/binaryop.py +.. _`doc/`: ../../pypy/doc +.. _`doc/revreport/`: ../../pypy/doc/revreport +.. _`interpreter/`: +.. _`pypy/interpreter`: ../../pypy/interpreter +.. _`pypy/interpreter/argument.py`: ../../pypy/interpreter/argument.py +.. _`pypy/interpreter/function.py`: ../../pypy/interpreter/function.py +.. _`pypy/interpreter/gateway.py`: ../../pypy/interpreter/gateway.py +.. _`pypy/interpreter/generator.py`: ../../pypy/interpreter/generator.py +.. _`pypy/interpreter/mixedmodule.py`: ../../pypy/interpreter/mixedmodule.py +.. _`pypy/interpreter/nestedscope.py`: ../../pypy/interpreter/nestedscope.py +.. _`pypy/interpreter/pyopcode.py`: ../../pypy/interpreter/pyopcode.py +.. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py .. _`lib/`: -.. _`pypy/lib/`: http://codespeak.net/svn/pypy/dist/pypy/lib +.. _`pypy/lib/`: ../../pypy/lib .. _`lib/test2/`: -.. _`pypy/lib/test2`: http://codespeak.net/svn/pypy/dist/pypy/lib/test2 +.. _`pypy/lib/test2`: ../../pypy/lib/test2 .. _`module/`: -.. _`pypy/module`: http://codespeak.net/svn/pypy/dist/pypy/module -.. _`module/__builtin__/`: http://codespeak.net/svn/pypy/dist/pypy/module/__builtin__ -.. _`pypy/module/__builtin__/__init__.py`: http://codespeak.net/svn/pypy/dist/pypy/module/__builtin__/__init__.py -.. _`module/_sre_pypy/`: http://codespeak.net/svn/pypy/dist/pypy/module/_sre_pypy -.. _`module/parser/`: http://codespeak.net/svn/pypy/dist/pypy/module/parser -.. _`module/recparser/`: http://codespeak.net/svn/pypy/dist/pypy/module/recparser -.. _`module/sys/`: http://codespeak.net/svn/pypy/dist/pypy/module/sys -.. _`pypy/objspace`: -.. _`objspace/`: http://codespeak.net/svn/pypy/dist/pypy/objspace -.. _`objspace/flow/`: http://codespeak.net/svn/pypy/dist/pypy/objspace/flow -.. _`pypy/objspace/std`: -.. _`objspace/std/`: http://codespeak.net/svn/pypy/dist/pypy/objspace/std -.. _`objspace/thunk.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/thunk.py +.. _`pypy/module`: ../../pypy/module +.. _`module/__builtin__/`: ../../pypy/module/__builtin__ +.. _`pypy/module/__builtin__/__init__.py`: ../../pypy/module/__builtin__/__init__.py +.. _`module/_sre_pypy/`: ../../pypy/module/_sre_pypy +.. _`module/parser/`: ../../pypy/module/parser +.. _`module/recparser/`: ../../pypy/module/recparser +.. _`module/sys/`: ../../pypy/module/sys +.. _`objspace/`: +.. _`pypy/objspace`: ../../pypy/objspace +.. _`objspace/flow/`: ../../pypy/objspace/flow +.. _`objspace/std/`: +.. _`pypy/objspace/std`: ../../pypy/objspace/std +.. _`objspace/thunk.py`: ../../pypy/objspace/thunk.py .. _`objspace/trace.py`: -.. _`pypy/objspace/trace.py`: http://codespeak.net/svn/pypy/dist/pypy/objspace/trace.py -.. _`rpython/`: http://codespeak.net/svn/pypy/dist/pypy/rpython -.. _`rpython/lltype.py`: http://codespeak.net/svn/pypy/dist/pypy/rpython/lltype.py -.. _`rpython/rint.py`: http://codespeak.net/svn/pypy/dist/pypy/rpython/rint.py -.. _`rpython/rlist.py`: http://codespeak.net/svn/pypy/dist/pypy/rpython/rlist.py -.. _`rpython/rmodel.py`: http://codespeak.net/svn/pypy/dist/pypy/rpython/rmodel.py -.. _`pypy/test_all.py`: http://codespeak.net/svn/pypy/dist/pypy/test_all.py -.. _`tool/`: http://codespeak.net/svn/pypy/dist/pypy/tool -.. _`tool/pytest/`: http://codespeak.net/svn/pypy/dist/pypy/tool/pytest -.. _`tool/tb_server/`: http://codespeak.net/svn/pypy/dist/pypy/tool/tb_server -.. _`pypy/translator`: -.. _`translator/`: http://codespeak.net/svn/pypy/dist/pypy/translator -.. _`pypy/translator/annrpython.py`: http://codespeak.net/svn/pypy/dist/pypy/translator/annrpython.py -.. _`translator/c/`: http://codespeak.net/svn/pypy/dist/pypy/translator/c -.. _`translator/java/`: http://codespeak.net/svn/pypy/dist/pypy/translator/java -.. _`translator/llvm2/`: http://codespeak.net/svn/pypy/dist/pypy/translator/llvm2 -.. _`translator/tool/`: http://codespeak.net/svn/pypy/dist/pypy/translator/tool \ No newline at end of file +.. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py +.. _`rpython/`: ../../pypy/rpython +.. _`rpython/lltype.py`: ../../pypy/rpython/lltype.py +.. _`rpython/rint.py`: ../../pypy/rpython/rint.py +.. _`rpython/rlist.py`: ../../pypy/rpython/rlist.py +.. _`rpython/rmodel.py`: ../../pypy/rpython/rmodel.py +.. _`pypy/test_all.py`: ../../pypy/test_all.py +.. _`tool/`: ../../pypy/tool +.. _`tool/pytest/`: ../../pypy/tool/pytest +.. _`tool/tb_server/`: ../../pypy/tool/tb_server +.. _`translator/`: +.. _`pypy/translator`: ../../pypy/translator +.. _`pypy/translator/annrpython.py`: ../../pypy/translator/annrpython.py +.. _`translator/c/`: ../../pypy/translator/c +.. _`translator/java/`: ../../pypy/translator/java +.. _`translator/llvm2/`: ../../pypy/translator/llvm2 +.. _`translator/tool/`: ../../pypy/translator/tool \ No newline at end of file Modified: pypy/branch/dist-newdoc/pypy/doc/coding-guide.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/doc/coding-guide.txt (original) +++ pypy/branch/dist-newdoc/pypy/doc/coding-guide.txt Mon Aug 22 18:50:50 2005 @@ -696,8 +696,6 @@ This allows us to quickly test our python-coded reimplementations against CPython. -.. _`pypy/lib/test2`: http://codespeak.net/svn/pypy/dist/pypy/lib/test2 - Testing modules in ``pypy/module`` ---------------------------------- Modified: pypy/branch/dist-newdoc/pypy/doc/index.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/doc/index.txt (original) +++ pypy/branch/dist-newdoc/pypy/doc/index.txt Mon Aug 22 18:50:50 2005 @@ -53,11 +53,9 @@ ============================ =========================================== `annotation/`_ `type inferencing code`_ for `RPython`_ programs -`documentation/`_ text versions of PyPy `documentation`_ files shown on the website +`doc/`_ text versions of PyPy developer documentation -`documentation/revreport/`_ the source code for the `revision report`_ - -`documentation/website/`_ text versions of the navigation webpages +`doc/revreport/`_ the source code for the `revision report`_ `interpreter/`_ `bytecode interpreter`_ and related objects (frames, functions, modules,...) Modified: pypy/branch/dist-newdoc/pypy/doc/svn-help.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/doc/svn-help.txt (original) +++ pypy/branch/dist-newdoc/pypy/doc/svn-help.txt Mon Aug 22 18:50:50 2005 @@ -30,7 +30,7 @@ For linux: -download the tarball. unzip and untar it. Then type *./configure*. Then, as root, *make* followed by *make install*. Voil? ... a subversion client. +download the tarball. unzip and untar it. Then type *./configure*. Then, as root, *make* followed by *make install*. Voila ... a subversion client. For Debian users:: Modified: pypy/branch/dist-newdoc/pypy/doc/tool/makeref.py ============================================================================== --- pypy/branch/dist-newdoc/pypy/doc/tool/makeref.py (original) +++ pypy/branch/dist-newdoc/pypy/doc/tool/makeref.py Mon Aug 22 18:50:50 2005 @@ -7,8 +7,8 @@ dist_url = 'http://codespeak.net/svn/pypy/dist/' issue_url = 'http://codespeak.net/issue/pypy-dev/' -docdir = pypydir.join('documentation') -reffile = pypydir.join('documentation', '_ref.txt') +docdir = pypydir.join('doc') +reffile = pypydir.join('doc', '_ref.txt') linkrex = py.std.re.compile('`(\S+)`_') @@ -27,7 +27,9 @@ for startloc in ('', 'pypy'): cand = distdir.join(startloc, linkname) if cand.check(): - target = dist_url + cand.relto(distdir) + rel = cand.relto(distdir) + # we are in pypy/doc/x.txt + target = '../../' + cand.relto(distdir) addlink(linkname, target) break else: From tismer at codespeak.net Mon Aug 22 18:56:56 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 22 Aug 2005 18:56:56 +0200 (CEST) Subject: [pypy-svn] r16224 - in pypy/dist/pypy: interpreter lib/_stablecompiler Message-ID: <20050822165656.1919127B41@code1.codespeak.net> Author: tismer Date: Mon Aug 22 18:56:54 2005 New Revision: 16224 Added: pypy/dist/pypy/lib/_stablecompiler/apphook.py (contents, props changed) Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: changed pycompiler for the case of pparseapp: always re-import the compiler from _stablecompiler.apphook Thismake it possible to change the function apphook.applevelcompile at any time in a compiled PyPy executable. Reasoning: I want to use the compiled PyPy to run the regression tests, but compiling with the applevelcompilermakes it useless, again. Instead, we use a fake via calling a real CPython process to do this. (coming next. First, I have to build a PyPy that has os.system) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Mon Aug 22 18:56:54 2005 @@ -240,28 +240,15 @@ PythonCompiler.__init__(self, space) debug_print("importing the 'compiler' package at app-level...", newline=False) - self.w_applevelcompile = space.appexec([], r'''(): - from _stablecompiler.misc import set_filename - from _stablecompiler.pycodegen import ModuleCodeGenerator - from _stablecompiler.pycodegen import InteractiveCodeGenerator - from _stablecompiler.pycodegen import ExpressionCodeGenerator - from _stablecompiler.transformer import Transformer - - def applevelcompile(tuples, filename, mode): - transformer = Transformer() - tree = transformer.compile_node(tuples) - set_filename(filename, tree) - if mode == 'exec': - codegenerator = ModuleCodeGenerator(tree) - elif mode == 'single': - codegenerator = InteractiveCodeGenerator(tree) - else: # mode == 'eval': - codegenerator = ExpressionCodeGenerator(tree) - return codegenerator.getCode() + self._load_compiler() + debug_print(" done") - return applevelcompile + def _load_compiler(self): + # doing this all the time, to allow patching + self.w_applevelcompile = self.space.appexec([], r'''(): + from _stablecompiler import apphook + return apphook.applevelcompile ''') - debug_print(" done") def compile_parse_result(self, parse_result, filename, mode): space = self.space @@ -281,6 +268,7 @@ w_nested_tuples, space.wrap(source_encoding)]) + self._load_compiler() w_code = space.call_function(self.w_applevelcompile, w_nested_tuples, space.wrap(filename), Added: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Mon Aug 22 18:56:54 2005 @@ -0,0 +1,24 @@ +# +# overridable part of applevel compiler +# function applevelcompile can be patched at runtime +# + +from _stablecompiler.misc import set_filename +from _stablecompiler.pycodegen import ModuleCodeGenerator +from _stablecompiler.pycodegen import InteractiveCodeGenerator +from _stablecompiler.pycodegen import ExpressionCodeGenerator +from _stablecompiler.transformer import Transformer + +def applevelcompile(tuples, filename, mode): + transformer = Transformer() + tree = transformer.compile_node(tuples) + set_filename(filename, tree) + if mode == 'exec': + codegenerator = ModuleCodeGenerator(tree) + elif mode == 'single': + codegenerator = InteractiveCodeGenerator(tree) + else: # mode == 'eval': + codegenerator = ExpressionCodeGenerator(tree) + return codegenerator.getCode() + +return applevelcompile From ale at codespeak.net Mon Aug 22 19:04:33 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 22 Aug 2005 19:04:33 +0200 (CEST) Subject: [pypy-svn] r16225 - pypy/dist/pypy/module/_codecs Message-ID: <20050822170433.D66E627B41@code1.codespeak.net> Author: ale Date: Mon Aug 22 19:04:32 2005 New Revision: 16225 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: (Jakob, Anders) Fun with byteorder in codecs. Added an extra consumed bytes return value from PyUnicode_DecodeUTF16Stateful Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Mon Aug 22 19:04:32 2005 @@ -164,9 +164,9 @@ def utf_8_decode( data,errors='strict',final=None): """None """ - res = PyUnicode_DecodeUTF8Stateful(data, len(data), errors, final) + res,consumed = PyUnicode_DecodeUTF8Stateful(data, len(data), errors, final) res = u''.join(res) - return res,len(res) + return res, consumed def raw_unicode_escape_decode( data,errors='strict'): """None @@ -199,7 +199,7 @@ def utf_16_decode( data,errors='strict',final=None): """None """ - res,consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors) + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors) res = ''.join(res) return res, consumed @@ -282,12 +282,12 @@ """None """ if byteorder == 0: - byteorder = 'native' + bm = 'native' elif byteorder == -1: - byteorder = 'little' + bm = 'little' else: - byteorder = 'big' - res,consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,byteorder) + bm = 'big' + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,bm) res = ''.join(res) return res, consumed, byteorder @@ -416,14 +416,14 @@ def utf_16_le_decode( data,errors='strict',byteorder=0, final = 0): """None """ - res,consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little') + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little') res = u''.join(res) return res, consumed def utf_16_be_decode( data,errors='strict',byteorder=0, final = 0): """None """ - res, consumed = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big') + res, consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big') res = u''.join(res) return res, consumed @@ -879,8 +879,6 @@ ihi = 0 ilo = 1 - if (size == 0): - return [u''] #/* Unpack UTF-16 encoded data */ @@ -913,6 +911,9 @@ else: bo = 1 + if (size == 0): + return [u''],0,bo + if (bo == -1): #/* force LE */ ihi = 1 @@ -974,7 +975,7 @@ endinpos = startinpos+2 unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) - return p,q + return p, q, bo # moved out of local scope, especially because it didn't # have any nested variables. @@ -1092,7 +1093,7 @@ if (size == 0): if (consumed): consumed = 0 - return u'' + return u'', consumed p = [] pos = 0 @@ -1248,7 +1249,7 @@ if (consumed): consumed = pos - return p + return p, consumed def PyUnicode_EncodeUTF8(s,size,errors): From hpk at codespeak.net Mon Aug 22 19:38:57 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 19:38:57 +0200 (CEST) Subject: [pypy-svn] r16226 - pypy/branch/dist-newdoc/pypy/doc Message-ID: <20050822173857.016AE27B41@code1.codespeak.net> Author: hpk Date: Mon Aug 22 19:38:57 2005 New Revision: 16226 Modified: pypy/branch/dist-newdoc/pypy/doc/confrest.py Log: fix url Modified: pypy/branch/dist-newdoc/pypy/doc/confrest.py ============================================================================== --- pypy/branch/dist-newdoc/pypy/doc/confrest.py (original) +++ pypy/branch/dist-newdoc/pypy/doc/confrest.py Mon Aug 22 19:38:57 2005 @@ -8,7 +8,7 @@ html.a("doc", href="index.html", class_="menu"), " ", html.a("contact", href="contact.html", class_="menu"), " ", html.a("getting-started", - href="getting_started.html", class_="menu"), " ", + href="getting-started.html", class_="menu"), " ", html.a("issue", href="https://codespeak.net/issue/pypy-dev/", class_="menu"), From tismer at codespeak.net Mon Aug 22 19:45:49 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 22 Aug 2005 19:45:49 +0200 (CEST) Subject: [pypy-svn] r16227 - pypy/dist/pypy/lib/_stablecompiler Message-ID: <20050822174549.1DF1627B41@code1.codespeak.net> Author: tismer Date: Mon Aug 22 19:45:48 2005 New Revision: 16227 Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py Log: cleanup Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Mon Aug 22 19:45:48 2005 @@ -20,5 +20,3 @@ else: # mode == 'eval': codegenerator = ExpressionCodeGenerator(tree) return codegenerator.getCode() - -return applevelcompile From arigo at codespeak.net Mon Aug 22 19:50:31 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 22 Aug 2005 19:50:31 +0200 (CEST) Subject: [pypy-svn] r16228 - in pypy/dist/pypy/translator: c c/src tool Message-ID: <20050822175031.C5B5227B43@code1.codespeak.net> Author: arigo Date: Mon Aug 22 19:50:29 2005 New Revision: 16228 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/g_prerequisite.h pypy/dist/pypy/translator/c/src/standalone.h pypy/dist/pypy/translator/tool/cbuild.py Log: (rxe, arigo) Broke test_standalone. Fix... Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Mon Aug 22 19:50:29 2005 @@ -173,6 +173,7 @@ defines['PYPY_STANDALONE'] = entrypointname for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) + print >> f, '#include "src/g_prerequisite.h"' preimplementationlines = list( pre_include_code_lines(database, database.translator.rtyper)) Modified: pypy/dist/pypy/translator/c/src/g_prerequisite.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_prerequisite.h (original) +++ pypy/dist/pypy/translator/c/src/g_prerequisite.h Mon Aug 22 19:50:29 2005 @@ -2,7 +2,13 @@ /**************************************************************/ /*** this is included before any code produced by genc.py ***/ +/* 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 + */ +#define Py_BUILD_CORE /* for Windows: avoid pulling libs in */ #include "Python.h" + #include "thread.h" /* needs to be included early to define the struct RPyOpaque_ThreadLock */ Modified: pypy/dist/pypy/translator/c/src/standalone.h ============================================================================== --- pypy/dist/pypy/translator/c/src/standalone.h (original) +++ pypy/dist/pypy/translator/c/src/standalone.h Mon Aug 22 19:50:29 2005 @@ -1,9 +1,3 @@ -/* 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 - */ -#define Py_BUILD_CORE /* for Windows: avoid pulling libs in */ -#include "Python.h" #include #include Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Mon Aug 22 19:50:29 2005 @@ -230,8 +230,11 @@ libraries=[]): from distutils.ccompiler import new_compiler ext = '' + extra_preargs = None if sys.platform != 'win32': libraries.append('m') + libraries.append('pthread') + extra_preargs = ['-pthread'] # XXX make this more general if outputfilename is None: outputfilename = py.path.local(cfilenames[0]).new(ext=ext) else: @@ -244,7 +247,8 @@ old = cfile.dirpath().chdir() try: res = compiler.compile([cfile.basename], - include_dirs=include_dirs) + include_dirs=include_dirs, + extra_preargs=extra_preargs) assert len(res) == 1 cobjfile = py.path.local(res[0]) assert cobjfile.check() @@ -252,6 +256,7 @@ finally: old.chdir() compiler.link_executable(objects, str(outputfilename), - libraries=libraries) + libraries=libraries, + extra_preargs=extra_preargs) return str(outputfilename) From pedronis at codespeak.net Mon Aug 22 20:01:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 22 Aug 2005 20:01:59 +0200 (CEST) Subject: [pypy-svn] r16229 - pypy/dist/pypy/translator/c Message-ID: <20050822180159.3155827B41@code1.codespeak.net> Author: pedronis Date: Mon Aug 22 20:01:57 2005 New Revision: 16229 Added: pypy/dist/pypy/translator/c/gc.py (contents, props changed) Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/funcgen.py Log: started factoring out refcounting logic as a pluggable gc policy. still to-do: factor out malloc impls and the gc-related logic in node.py . (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Mon Aug 22 20:01:57 2005 @@ -8,12 +8,13 @@ from pypy.translator.c.node import ContainerNodeClass, ExtTypeOpaqueDefNode from pypy.translator.c.support import cdecl, CNameManager, ErrorValue from pypy.translator.c.pyobj import PyObjMaker +from pypy.translator.c import gc # ____________________________________________________________ class LowLevelDatabase: - def __init__(self, translator=None, standalone=False): + def __init__(self, translator=None, standalone=False, gcpolicy=gc.RefcountingGcPolicy): self.translator = translator self.standalone = standalone self.structdefnodes = {} @@ -23,6 +24,7 @@ self.namespace = CNameManager() if not standalone: self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator) + self.gcpolicy = gcpolicy(self) def gettypedefnode(self, T, varlength=1): if varlength <= 1: Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Mon Aug 22 20:01:57 2005 @@ -124,7 +124,7 @@ yield '{' yield '\t%s;' % cdecl(exc_value_typename, 'vanishing_exc_value') yield '\tRPyConvertExceptionToCPython(vanishing_exc_value);' - yield '\t%s' % self.db.cdecrefstmt('vanishing_exc_value', lltype_of_exception_value) + yield '\t%s' % self.pop_alive_expr('vanishing_exc_value', lltype_of_exception_value) yield '}' yield 'return %s; ' % self.error_return_value() @@ -156,21 +156,21 @@ blocknum = {} allblocks = [] - # generate an incref for each input argument + # match the subsequent pop_alive for each input argument for a in self.graph.getargs(): - line = self.cincref(a) + line = self.push_alive(a) if line: yield line def gen_link(link, linklocalvars=None): "Generate the code to jump across the given Link." - has_ref = {} + is_alive = {} linklocalvars = linklocalvars or {} for v in to_release: linklocalvars[v] = self.expr(v) - has_ref = linklocalvars.copy() + is_alive = linklocalvars.copy() assignments = [] - increfs = [] + stay_alive = [] for a1, a2 in zip(link.args, link.target.inputargs): if self.lltypemap(a2) == Void: continue @@ -180,23 +180,23 @@ src = self.expr(a1) dest = self.expr(a2) assignments.append((self.lltypename(a2), dest, src)) - if a1 in has_ref: - del has_ref[a1] + if a1 in is_alive: + del is_alive[a1] else: assert self.lltypemap(a1) == self.lltypemap(a2) - increfs.append(a2) + stay_alive.append(a2) # warning, the order below is delicate to get right: - # 1. decref the old variables that are not passed over - for v in has_ref: - line = self.cdecref(v, linklocalvars[v]) + # 1. forget the old variables that are not passed over + for v in is_alive: + line = self.pop_alive(v, linklocalvars[v]) if line: yield line # 2. perform the assignments with collision-avoidance for line in gen_assignments(assignments): yield line - # 3. incref the new variables if needed - for a2 in increfs: - line = self.cincref(a2) + # 3. keep alive the new variables if needed + for a2 in stay_alive: + line = self.push_alive(a2) if line: yield line yield 'goto block%d;' % blocknum[link.target] @@ -228,10 +228,9 @@ yield '%s(%s);' % (macro, ', '.join(lst)) to_release.append(op.result) - if op.opname !='direct_call' and self.lltypemap(op.result) != PyObjPtr: # xxx factor out - line = self.cincref(op.result) - if line: - yield line + line = self.db.gcpolicy.push_alive_op_result(op.opname, LOCALVAR % op.result.name, self.lltypemap(op.result)) + if line: + yield line err_reachable = False if len(block.exits) == 0: @@ -290,11 +289,11 @@ if isinstance(link.last_exception, Variable): d[link.last_exception] = 'exc_cls' else: - yield '\t' + self.db.cdecrefstmt('exc_cls', T1) + yield '\t' + self.pop_alive_expr('exc_cls', T1) if isinstance(link.last_exc_value, Variable): d[link.last_exc_value] = 'exc_value' else: - yield '\t' + self.db.cdecrefstmt('exc_value', T2) + yield '\t' + self.pop_alive_expr('exc_value', T2) for op in gen_link(link, d): yield '\t' + op yield '}' @@ -333,7 +332,7 @@ while to_release: v = to_release.pop() if err_reachable: - yield self.cdecref(v) + yield self.pop_alive(v) yield 'err%d_%d:' % (blocknum[block], len(to_release)) err_reachable = True if err_reachable: @@ -400,10 +399,9 @@ result = ['%s = %s;' % (newvalue, sourceexpr)] # need to adjust the refcount of the result - if T == PyObjPtr: # xxx factor out - increfstmt = self.db.cincrefstmt(newvalue, T) - if increfstmt: - result.append(increfstmt) + line = self.pyobj_incref_expr(newvalue, T) + if line: + result.append(line) result = '\t'.join(result) if T == Void: result = '/* %s */' % result @@ -412,18 +410,9 @@ def generic_set(self, op, targetexpr): newvalue = self.expr(op.args[2], special_case_void=False) result = ['%s = %s;' % (targetexpr, newvalue)] - # need to adjust some refcounts + # insert write barrier T = self.lltypemap(op.args[2]) - decrefstmt = self.db.cdecrefstmt('prev', T) # xxx factor out write barrier - increfstmt = self.db.cincrefstmt(newvalue, T) - if increfstmt: - result.append(increfstmt) - if decrefstmt: - result.insert(0, '{ %s = %s;' % ( - cdecl(self.lltypename(op.args[2]), 'prev'), - targetexpr)) - result.append(decrefstmt) - result.append('}') + self.db.gcpolicy.write_barrier(result, newvalue, T, targetexpr) result = '\t'.join(result) if T == Void: result = '/* %s */' % result @@ -531,10 +520,10 @@ result.append('%s = (%s)%s;' % (self.expr(op.result), cdecl(typename, ''), self.expr(op.args[0]))) - if TYPE == PyObjPtr: # xxx factor out - line = self.cincref(op.result) - if line: - result.append(line) + + line = self.pyobj_incref(op.result) + if line: + result.append(line) return '\t'.join(result) def OP_SAME_AS(self, op, err): @@ -544,18 +533,34 @@ if TYPE != Void: result.append('%s = %s;' % (self.expr(op.result), self.expr(op.args[0]))) - if TYPE == PyObjPtr: # xxx factor out - line = self.cincref(op.result) - if line: - result.append(line) + line = self.pyobj_incref(op.result) + if line: + result.append(line) return '\t'.join(result) - def cincref(self, v): + def pyobj_incref(self, v): T = self.lltypemap(v) - return self.db.cincrefstmt(LOCALVAR % v.name, T) + return self.pyobj_incref_expr(LOCALVAR % v.name, T) - def cdecref(self, v, expr=None): + def pyobj_incref_expr(self, expr, T): + return self.db.gcpolicy.pyobj_incref(expr, T) + + def pyobj_decref_expr(self, expr, T): + return self.db.gcpolicy.pyobj_decref(expr, T) + + def push_alive(self, v): + T = self.lltypemap(v) + return self.push_alive_expr(LOCALVAR % v.name, T) + + def pop_alive(self, v, expr=None): T = self.lltypemap(v) - return self.db.cdecrefstmt(expr or (LOCALVAR % v.name), T) + return self.pop_alive_expr(expr or (LOCALVAR % v.name), T) + + def push_alive_expr(self, expr, T): + return self.db.gcpolicy.push_alive(expr, T) + + def pop_alive_expr(self, expr, T): + return self.db.gcpolicy.pop_alive(expr, T) + assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Added: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/gc.py Mon Aug 22 20:01:57 2005 @@ -0,0 +1,70 @@ +from pypy.translator.c.support import cdecl +from pypy.rpython.lltype import Ptr, PyObject + +PyObjPtr = Ptr(PyObject) + +class BasicGcPolicy: + + def __init__(self, db): + self.db = db + + def pyobj_incref(self, expr, T): + if T == PyObjPtr: + return 'Py_XINCREF(%s);' % expr + return '' + + def pyobj_decref(self, expr, T): + return 'Py_XDECREF(%s);' % expr + + def push_alive(self, expr, T): + if isinstance(T, Ptr) and T._needsgc(): + if expr == 'NULL': # hum + return '' + if T.TO == PyObject: + return self.pyobj_incref(expr, T) + else: + return self.push_alive_nopyobj(expr, T) + return '' + + def pop_alive(self, expr, T): + if isinstance(T, Ptr) and T._needsgc(): + if T.TO == PyObject: + return self.pyobj_decref(expr, T) + else: + return self.pop_alive_nopyobj(expr, T) + return '' + + +class RefcountingGcPolicy(BasicGcPolicy): + + def push_alive_nopyobj(self, expr, T): + defnode = self.db.gettypedefnode(T.TO) + if defnode.refcount is not None: + return 'if (%s) %s->%s++;' % (expr, expr, defnode.refcount) + + def pop_alive_nopyobj(self, expr, T): + defnode = self.db.gettypedefnode(T.TO) + if defnode.refcount is not None: + return 'if (%s && !--%s->%s) %s(%s);' % (expr, expr, + defnode.refcount, + defnode.deallocator or 'OP_FREE', + expr) + + def push_alive_op_result(self, opname, expr, T): + if opname !='direct_call' and T != PyObjPtr: + return self.push_alive(expr, T) + return '' + + def write_barrier(self, result, newvalue, T, targetexpr): + decrefstmt = self.pop_alive('prev', T) + increfstmt = self.push_alive(newvalue, T) + if increfstmt: + result.append(increfstmt) + if decrefstmt: + result.insert(0, '{ %s = %s;' % ( + cdecl(self.db.gettype(T), 'prev'), + targetexpr)) + result.append(decrefstmt) + result.append('}') + + From jacob at codespeak.net Mon Aug 22 20:30:27 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Mon, 22 Aug 2005 20:30:27 +0200 (CEST) Subject: [pypy-svn] r16231 - pypy/dist/pypy/lib Message-ID: <20050822183027.0B5D427B41@code1.codespeak.net> Author: jacob Date: Mon Aug 22 20:30:26 2005 New Revision: 16231 Modified: pypy/dist/pypy/lib/binascii.py Log: Fixed 2.4.1 regressions. Modified: pypy/dist/pypy/lib/binascii.py ============================================================================== --- pypy/dist/pypy/lib/binascii.py (original) +++ pypy/dist/pypy/lib/binascii.py Mon Aug 22 20:30:26 2005 @@ -8,6 +8,9 @@ pass def a2b_uu(s): + if not s: + return '' + length = (ord(s[0]) - 0x20) % 64 def quadruplets_gen(s): @@ -255,9 +258,14 @@ linebreak = '\r\n' elif lf > 0: linebreak = '\n' - + + # if linebreak and linebreak == '\r\n': + # The above is more efficient for files with \n linebreaks, + # but fails badly on files with mixed linebreak encoding if linebreak: s = s.replace('\r\n', '\n') + else: + linebreak = '\n' lines = s.split('\n') @@ -494,6 +502,8 @@ The CPython implementation does not do run length encoding of \x90 characters. This implementation does. """ + if not s: + return '' result = [] prev = s[0] count = 1 @@ -602,6 +612,7 @@ ] def crc32(s, crc=0): + result = 0 crc = ~long(crc) & 0xffffffffL for c in s: crc = crc_32_tab[(crc ^ long(ord(c))) & 0xffL] ^ (crc >> 8) From tismer at codespeak.net Mon Aug 22 20:36:50 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 22 Aug 2005 20:36:50 +0200 (CEST) Subject: [pypy-svn] r16232 - in pypy/dist/pypy/translator/c: . src Message-ID: <20050822183650.24CB227B41@code1.codespeak.net> Author: tismer Date: Mon Aug 22 20:36:48 2005 New Revision: 16232 Modified: pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_os.h Log: implemented os.system Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Mon Aug 22 20:36:48 2005 @@ -22,6 +22,7 @@ ll_os .ll_os_isatty: 'LL_os_isatty', ll_os .ll_os_ftruncate:'LL_os_ftruncate', ll_os .ll_os_strerror: 'LL_os_strerror', + ll_os .ll_os_system: 'LL_os_system', ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', ll_time.ll_time_time: 'LL_time_time', Modified: pypy/dist/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_os.h (original) +++ pypy/dist/pypy/translator/c/src/ll_os.h Mon Aug 22 20:36:48 2005 @@ -174,9 +174,12 @@ } #endif -RPyString *LL_os_strerror(int errnum) -{ +RPyString *LL_os_strerror(int errnum) { char *res; res = strerror(errnum); return RPyString_FromString(res); } + +long LL_os_system(RPyString * fname) { + return system(RPyString_AsString(fname)); +} From cfbolz at codespeak.net Mon Aug 22 21:24:51 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 22 Aug 2005 21:24:51 +0200 (CEST) Subject: [pypy-svn] r16233 - pypy/dist/pypy/rpython/memory Message-ID: <20050822192451.737AE27B41@code1.codespeak.net> Author: cfbolz Date: Mon Aug 22 21:24:47 2005 New Revision: 16233 Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py Log: oops, forgot float at some point long ago Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypelayout.py (original) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Mon Aug 22 21:24:47 2005 @@ -7,6 +7,7 @@ lltype.Unsigned: "I", lltype.Char: "c", lltype.Bool: "B", + lltype.Float: "d", lladdress.Address: "P", } From ericvrp at codespeak.net Mon Aug 22 21:35:09 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 22 Aug 2005 21:35:09 +0200 (CEST) Subject: [pypy-svn] r16234 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050822193509.19BE827B41@code1.codespeak.net> Author: ericvrp Date: Mon Aug 22 21:35:07 2005 New Revision: 16234 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/opwriter.py pypy/dist/pypy/translator/llvm2/structnode.py pypy/dist/pypy/translator/llvm2/varsize.py Log: * another step toward 64bit support Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Mon Aug 22 21:35:07 2005 @@ -8,10 +8,12 @@ DEFAULT_CCONV = 'fastcc' #or 'ccc' class CodeWriter(object): - def __init__(self, f, show_line_number=False): + def __init__(self, f, word, uword, show_line_number=False): self.f = f self.show_line_numbers = show_line_number self.n_lines = 0 + self.word = word + self.uword = uword def append(self, line): self.n_lines += 1 @@ -145,13 +147,16 @@ else: cnt = "" postfix = ('', '_atomic')[atomic] - self.indent("%%malloc.Size%(cnt)s = getelementptr %(type_)s* null, uint %(size)s" % locals()) - self.indent("%%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to uint" % locals()) - self.indent("%%malloc.Ptr%(cnt)s = call %(cconv)s sbyte* %%gc_malloc%(postfix)s(uint %%malloc.SizeU%(cnt)s)" % locals()) + word = self.word + uword = self.uword + self.indent("%%malloc.Size%(cnt)s = getelementptr %(type_)s* null, %(uword)s %(size)s" % locals()) + self.indent("%%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to %(uword)s" % locals()) + self.indent("%%malloc.Ptr%(cnt)s = call %(cconv)s sbyte* %%gc_malloc%(postfix)s(%(uword)s %%malloc.SizeU%(cnt)s)" % locals()) self.indent("%(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s*" % locals()) def getelementptr(self, targetvar, type, typevar, *indices): - res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, int 0, " % locals() + word = self.word + res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, %(word)s 0, " % locals() res += ", ".join(["%s %s" % (t, i) for t, i in indices]) self.indent(res) @@ -163,7 +168,8 @@ "%(valuetype)s* %(ptr)s" % locals()) def debugcomment(self, tempname, len, tmpname): - res = "%s = tail call ccc int (sbyte*, ...)* %%printf(" - res += "sbyte* getelementptr ([%s x sbyte]* %s, int 0, int 0) )" + word = self.word + res = "%s = tail call ccc %(word)s (sbyte*, ...)* %%printf(" % locals() + res += "sbyte* getelementptr ([%s x sbyte]* %s, %(word)s 0, %(word)s 0) )" % locals() res = res % (tmpname, len, tmpname) self.indent(res) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Mon Aug 22 21:35:07 2005 @@ -67,7 +67,10 @@ assert False return decls - + + def replace_with_machine_words(self, s): + return s.replace('UINT',self.db.get_machine_uword()).replace('INT',self.db.get_machine_word()) + def gen_llvm_source(self, func=None): if self.debug: print 'gen_llvm_source begin) ' + time.ctime() if func is None: @@ -106,7 +109,7 @@ function_count[func.func_name] = 1 filename = udir.join(func.func_name + postfix).new(ext='.ll') f = open(str(filename),'w') - codewriter = CodeWriter(f) + codewriter = CodeWriter(f, self.db.get_machine_word(), self.db.get_machine_uword()) comment = codewriter.comment nl = codewriter.newline @@ -142,7 +145,7 @@ if self.debug: print 'gen_llvm_source extdeclarations) ' + time.ctime() nl(); comment("Function Prototypes") ; nl() - for extdecl in extdeclarations.split('\n'): + for extdecl in self.replace_with_machine_words(extdeclarations).split('\n'): codewriter.append(extdecl) if self.debug: print 'gen_llvm_source self._debug_prototype) ' + time.ctime() @@ -160,7 +163,7 @@ gc_funcs = gc_boehm else: gc_funcs = gc_disabled - for gc_func in gc_funcs.split('\n'): + for gc_func in self.replace_with_machine_words(gc_funcs).split('\n'): codewriter.append(gc_func) if self.debug: print 'gen_llvm_source typ_decl.writeimpl) ' + time.ctime() @@ -215,7 +218,7 @@ codewriter.comment('XXX: Error: ' + msg) #raise Exception('primitive function %s has no implementation' %(dep,)) continue - for extfunc in llvm_code.split('\n'): + for extfunc in self.replace_with_machine_words(llvm_code).split('\n'): codewriter.append(extfunc) depdone[dep] = True Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Mon Aug 22 21:35:07 2005 @@ -1,35 +1,37 @@ extdeclarations = """;rpython stuff ;gc-type dependent mallocs -declare fastcc sbyte* %gc_malloc(uint) -declare fastcc sbyte* %gc_malloc_atomic(uint) +declare fastcc sbyte* %gc_malloc(UINT) +declare fastcc sbyte* %gc_malloc_atomic(UINT) ;exception handling globals %last_exception_type = global %RPYTHON_EXCEPTION_VTABLE* null %last_exception_value = global %RPYTHON_EXCEPTION* null """ -gc_boehm = """declare ccc sbyte* %GC_malloc(uint) -declare ccc sbyte* %GC_malloc_atomic(uint) +gc_boehm = """declare ccc sbyte* %GC_malloc(UINT) +declare ccc sbyte* %GC_malloc_atomic(UINT) -internal fastcc sbyte* %gc_malloc(uint %n) { - %ptr = call ccc sbyte* %GC_malloc(uint %n) +internal fastcc sbyte* %gc_malloc(UINT %n) { + %ptr = call ccc sbyte* %GC_malloc(UINT %n) ret sbyte* %ptr } -internal fastcc sbyte* %gc_malloc_atomic(uint %n) { - %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) +internal fastcc sbyte* %gc_malloc_atomic(UINT %n) { + %ptr = call ccc sbyte* %GC_malloc_atomic(UINT %n) ret sbyte* %ptr } """ -gc_disabled = """internal fastcc sbyte* %gc_malloc(uint %n) { - %ptr = malloc sbyte, uint %n +gc_disabled = """internal fastcc sbyte* %gc_malloc(UINT %n) { + %nn = cast UINT %n to uint + %ptr = malloc sbyte, uint %nn ret sbyte* %ptr } -internal fastcc sbyte* %gc_malloc_atomic(uint %n) { - %ptr = malloc sbyte, uint %n +internal fastcc sbyte* %gc_malloc_atomic(UINT %n) { + %nn = cast UINT %n to uint + %ptr = malloc sbyte, uint %nn ret sbyte* %ptr } """ Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Mon Aug 22 21:35:07 2005 @@ -62,7 +62,7 @@ """) extfunctions["%ll_math_ldexp"] = (("%__debug",), """ -internal fastcc double %ll_math_ldexp(double %x, int %y) { +internal fastcc double %ll_math_ldexp(double %x, INT %y) { call fastcc void %__debug([12 x sbyte]* %__ll_math_ldexp) ; XXX: TODO: ll_math_ldexp ret double 0.0 } Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Mon Aug 22 21:35:07 2005 @@ -1,17 +1,17 @@ extdeclarations = """ ;ll_os.py -declare ccc int %dup(int) -declare ccc void %close(int) -declare ccc int %open(sbyte*, int, int) -declare ccc int %write(int, sbyte*, int) -declare ccc int %read(int, sbyte*, int) +declare ccc INT %dup(INT) +declare ccc void %close(INT) +declare ccc INT %open(sbyte*, INT, INT) +declare ccc INT %write(INT, sbyte*, INT) +declare ccc INT %read(INT, sbyte*, INT) declare ccc sbyte* %strncpy(sbyte*, sbyte*, int) -declare ccc int %isatty(int) -declare ccc int %stat(sbyte*, [32 x int]*) -declare ccc int %fstat(int, [32 x int]*) -declare ccc int %lseek(int, int, int) -declare ccc int %ftruncate(int, int) -declare ccc sbyte* %getcwd(sbyte*, int) +declare ccc INT %isatty(INT) +declare ccc INT %stat(sbyte*, [32 x INT]*) +declare ccc INT %fstat(INT, [32 x INT]*) +declare ccc INT %lseek(INT, INT, INT) +declare ccc INT %ftruncate(INT, INT) +declare ccc sbyte* %getcwd(sbyte*, INT) %errno = external global int @@ -25,9 +25,9 @@ extfunctions = {} extfunctions["%ll_os_dup"] = ((), """ -internal fastcc int %ll_os_dup(int %fd) { - %ret = call ccc int %dup(int %fd) - ret int %ret +internal fastcc INT %ll_os_dup(INT %fd) { + %ret = call ccc INT %dup(INT %fd) + ret INT %ret } """) @@ -37,8 +37,8 @@ call fastcc void %__debug([12 x sbyte]* %__ll_os_getcwd) ; XXX: Test: ll_os_getcwd - %s = alloca sbyte, uint 1024 - %res = call ccc sbyte* %getcwd(sbyte* %s, int 1023) + %s = alloca sbyte, UINT 1024 + %res = call ccc sbyte* %getcwd(sbyte* %s, INT 1023) ;if %res == null: raise... %cwd = call fastcc %RPyString* %string_to_RPyString(sbyte* %s) @@ -48,103 +48,103 @@ """) extfunctions["%ll_os_close"] = ((), """ -internal fastcc void %ll_os_close(int %fd) { - call ccc void %close(int %fd) +internal fastcc void %ll_os_close(INT %fd) { + call ccc void %close(INT %fd) ret void } """) extfunctions["%ll_os_open"] = (("%cast",), """ -internal fastcc int %ll_os_open(%RPyString* %structstring, int %flag, int %mode) { +internal fastcc INT %ll_os_open(%RPyString* %structstring, INT %flag, INT %mode) { %dest = call fastcc sbyte* %cast(%RPyString* %structstring) - %fd = call ccc int %open(sbyte* %dest, int %flag, int %mode) - ret int %fd + %fd = call ccc INT %open(sbyte* %dest, INT %flag, INT %mode) + ret INT %fd } """) extfunctions["%ll_os_write"] = (("%cast",), """ -internal fastcc int %ll_os_write(int %fd, %RPyString* %structstring) { +internal fastcc INT %ll_os_write(INT %fd, %RPyString* %structstring) { %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 - %reallength = load int* %reallengthptr + %reallength = load INT* %reallengthptr %dest = call fastcc sbyte* %cast(%RPyString* %structstring) - %byteswritten = call ccc int %write(int %fd, sbyte* %dest, int %reallength) - ret int %byteswritten + %byteswritten = call ccc INT %write(INT %fd, sbyte* %dest, INT %reallength) + ret INT %byteswritten } """) extfunctions["%ll_read_into"] = ((), """ -internal fastcc int %ll_read_into(int %fd, %RPyString* %structstring) { +internal fastcc INT %ll_read_into(INT %fd, %RPyString* %structstring) { %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 - %reallength = load int* %reallengthptr + %reallength = load INT* %reallengthptr %destptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 %dest = cast [0 x sbyte]* %destptr to sbyte* - %bytesread = call ccc int %read(int %fd, sbyte* %dest, int %reallength) - ret int %bytesread + %bytesread = call ccc INT %read(INT %fd, sbyte* %dest, INT %reallength) + ret INT %bytesread } """) extfunctions["%ll_os_isatty"] = ((), """ -internal fastcc bool %ll_os_isatty(int %fd) { - %ret = call ccc int %isatty(int %fd) - %ret.bool = cast int %ret to bool +internal fastcc bool %ll_os_isatty(INT %fd) { + %ret = call ccc INT %isatty(INT %fd) + %ret.bool = cast INT %ret to bool ret bool %ret.bool } """) extfunctions["%ll_os_ftruncate"] = (("%__debug",), """ -internal fastcc void %ll_os_ftruncate(int %fd, int %length) { +internal fastcc void %ll_os_ftruncate(INT %fd, INT %length) { call fastcc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: Test: ll_os_ftruncate - %res = call ccc int %ftruncate(int %fd, int %length) + %res = call ccc INT %ftruncate(INT %fd, INT %length) ;if res < 0 raise... ret void } """) extfunctions["%ll_os_lseek"] = (("%__debug",), """ -internal fastcc int %ll_os_lseek(int %fd, int %pos, int %how) { +internal fastcc INT %ll_os_lseek(INT %fd, INT %pos, INT %how) { call fastcc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: Test: ll_os_lseek ;TODO: determine correct %how - %res = call ccc int %lseek(int %fd, int %pos, int %how) + %res = call ccc INT %lseek(INT %fd, INT %pos, INT %how) ;if res < 0 raise... - ret int %res + ret INT %res } """) extfunctions["%_stat_construct_result_helper"] = ((), """ -internal fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %src) { +internal fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x INT]* %src) { - %src0ptr = getelementptr [32 x int]* %src, int 0, uint 4 ;st_mode - %src1ptr = getelementptr [32 x int]* %src, int 0, uint 3 ;st_ino - %src2ptr = getelementptr [32 x int]* %src, int 0, uint 0 ;st_dev - %src3ptr = getelementptr [32 x int]* %src, int 0, uint 5 ;st_nlink - %src4ptr = getelementptr [32 x int]* %src, int 0, uint 6 ;st_uid - %src5ptr = getelementptr [32 x int]* %src, int 0, uint 7 ;st_gid - %src6ptr = getelementptr [32 x int]* %src, int 0, uint 11 ;st_size - %src7ptr = getelementptr [32 x int]* %src, int 0, uint 14 ;st_atime - %src8ptr = getelementptr [32 x int]* %src, int 0, uint 16 ;st_mtime - %src9ptr = getelementptr [32 x int]* %src, int 0, uint 18 ;st_ctime - - %src0 = load int* %src0ptr - %src1 = load int* %src1ptr - %src2 = load int* %src2ptr - %src3 = load int* %src3ptr - %src4 = load int* %src4ptr - %src5 = load int* %src5ptr - %src6 = load int* %src6ptr - %src7 = load int* %src7ptr - %src8 = load int* %src8ptr - %src9 = load int* %src9ptr + %src0ptr = getelementptr [32 x INT]* %src, int 0, uint 4 ;st_mode + %src1ptr = getelementptr [32 x INT]* %src, int 0, uint 3 ;st_ino + %src2ptr = getelementptr [32 x INT]* %src, int 0, uint 0 ;st_dev + %src3ptr = getelementptr [32 x INT]* %src, int 0, uint 5 ;st_nlink + %src4ptr = getelementptr [32 x INT]* %src, int 0, uint 6 ;st_uid + %src5ptr = getelementptr [32 x INT]* %src, int 0, uint 7 ;st_gid + %src6ptr = getelementptr [32 x INT]* %src, int 0, uint 11 ;st_size + %src7ptr = getelementptr [32 x INT]* %src, int 0, uint 14 ;st_atime + %src8ptr = getelementptr [32 x INT]* %src, int 0, uint 16 ;st_mtime + %src9ptr = getelementptr [32 x INT]* %src, int 0, uint 18 ;st_ctime + + %src0 = load INT* %src0ptr + %src1 = load INT* %src1ptr + %src2 = load INT* %src2ptr + %src3 = load INT* %src3ptr + %src4 = load INT* %src4ptr + %src5 = load INT* %src5ptr + %src6 = load INT* %src6ptr + %src7 = load INT* %src7ptr + %src8 = load INT* %src8ptr + %src9 = load INT* %src9ptr %malloc.Size = getelementptr %RPySTAT_RESULT* null, uint 1 - %malloc.SizeU = cast %RPySTAT_RESULT* %malloc.Size to uint - %malloc.Ptr = call fastcc sbyte* %gc_malloc_atomic(uint %malloc.SizeU) + %malloc.SizeU = cast %RPySTAT_RESULT* %malloc.Size to UINT + %malloc.Ptr = call fastcc sbyte* %gc_malloc_atomic(UINT %malloc.SizeU) %dest = cast sbyte* %malloc.Ptr to %RPySTAT_RESULT* %dest0ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 0 @@ -158,16 +158,16 @@ %dest8ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 8 %dest9ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 9 - store int %src0, int* %dest0ptr - store int %src1, int* %dest1ptr - store int %src2, int* %dest2ptr - store int %src3, int* %dest3ptr - store int %src4, int* %dest4ptr - store int %src5, int* %dest5ptr - store int %src6, int* %dest6ptr - store int %src7, int* %dest7ptr - store int %src8, int* %dest8ptr - store int %src9, int* %dest9ptr + store INT %src0, INT* %dest0ptr + store INT %src1, INT* %dest1ptr + store INT %src2, INT* %dest2ptr + store INT %src3, INT* %dest3ptr + store INT %src4, INT* %dest4ptr + store INT %src5, INT* %dest5ptr + store INT %src6, INT* %dest6ptr + store INT %src7, INT* %dest7ptr + store INT %src8, INT* %dest8ptr + store INT %src9, INT* %dest9ptr ret %RPySTAT_RESULT* %dest } @@ -178,40 +178,40 @@ call fastcc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat - %st = alloca [32 x int] + %st = alloca [32 x INT] %filename = call fastcc sbyte* %cast(%RPyString* %s) - %error = call ccc int %stat(sbyte* %filename, [32 x int]* %st) - %cond = seteq int %error, 0 + %error = call ccc INT %stat(sbyte* %filename, [32 x INT]* %st) + %cond = seteq INT %error, 0 br bool %cond, label %cool, label %bwa bwa: - %errno_ = load int* %errno - call fastcc void %ll_raise_OSError__Signed(int %errno_) + %errno_ = load INT* %errno + call fastcc void %ll_raise_OSError__Signed(INT %errno_) ret %RPySTAT_RESULT* null cool: - %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) + %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x INT]* %st) ret %RPySTAT_RESULT* %result } """) extfunctions["%ll_os_fstat"] = (("%__debug", "%_stat_construct_result_helper"), """ -internal fastcc %RPySTAT_RESULT* %ll_os_fstat(int %fd) { +internal fastcc %RPySTAT_RESULT* %ll_os_fstat(INT %fd) { call fastcc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat - %st = alloca [32 x int] - %error = call ccc int %fstat(int %fd, [32 x int]* %st) - %cond = seteq int %error, 0 + %st = alloca [32 x INT] + %error = call ccc INT %fstat(INT %fd, [32 x INT]* %st) + %cond = seteq INT %error, 0 br bool %cond, label %cool, label %bwa bwa: - %errno_ = load int* %errno - call fastcc void %ll_raise_OSError__Signed(int %errno_) + %errno_ = load INT* %errno + call fastcc void %ll_raise_OSError__Signed(INT %errno_) ret %RPySTAT_RESULT* null cool: - %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) + %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x INT]* %st) ret %RPySTAT_RESULT* %result } Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Mon Aug 22 21:35:07 2005 @@ -1,18 +1,18 @@ extdeclarations = ''' ;ll_time.py -%struct.timeval = type { int, int } -%struct.timezone = type { int, int } -%typedef.fd_set = type { [32 x int] } +%struct.timeval = type { INT, INT } +%struct.timezone = type { INT, INT } +%typedef.fd_set = type { [32 x INT] } %.str_1 = internal constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] declare ccc double %floor(double) declare ccc double %fmod(double, double) -declare ccc int %clock() -declare ccc int %select(int, %typedef.fd_set*, %typedef.fd_set*, %typedef.fd_set*, %struct.timeval*) -declare ccc int %gettimeofday(%struct.timeval*, %struct.timeval*) -declare ccc int %time( int* ) +declare ccc INT %clock() +declare ccc INT %select(INT, %typedef.fd_set*, %typedef.fd_set*, %typedef.fd_set*, %struct.timeval*) +declare ccc INT %gettimeofday(%struct.timeval*, %struct.timeval*) +declare ccc INT %time( INT* ) ''' extfunctions = {} @@ -21,27 +21,27 @@ internal fastcc double %ll_time_time() { %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] - %secs = alloca int ; [#uses=2] - %tmp.0 = call int %gettimeofday( %struct.timeval* %t, %struct.timeval* null ) ; [#uses=1] - %tmp.1 = seteq int %tmp.0, 0 ; [#uses=2] - %tmp.2 = cast bool %tmp.1 to int ; [#uses=0] + %secs = alloca INT ; [#uses=2] + %tmp.0 = call INT %gettimeofday( %struct.timeval* %t, %struct.timeval* null ) ; [#uses=1] + %tmp.1 = seteq INT %tmp.0, 0 ; [#uses=2] + %tmp.2 = cast bool %tmp.1 to INT ; [#uses=0] br bool %tmp.1, label %then, label %endif then: ; preds = %entry %tmp.3 = getelementptr %struct.timeval* %t, int 0, uint 0 ; [#uses=1] - %tmp.4 = load int* %tmp.3 ; [#uses=1] - %tmp.5 = cast int %tmp.4 to double ; [#uses=1] + %tmp.4 = load INT* %tmp.3 ; [#uses=1] + %tmp.5 = cast INT %tmp.4 to double ; [#uses=1] %tmp.6 = getelementptr %struct.timeval* %t, int 0, uint 1 ; [#uses=1] - %tmp.7 = load int* %tmp.6 ; [#uses=1] - %tmp.8 = cast int %tmp.7 to double ; [#uses=1] + %tmp.7 = load INT* %tmp.6 ; [#uses=1] + %tmp.8 = cast INT %tmp.7 to double ; [#uses=1] %tmp.9 = mul double %tmp.8, 1.000000e-06 ; [#uses=1] %tmp.10 = add double %tmp.5, %tmp.9 ; [#uses=1] ret double %tmp.10 endif: ; preds = %entry - %tmp.11 = call int %time( int* %secs ) ; [#uses=0] - %tmp.12 = load int* %secs ; [#uses=1] - %tmp.13 = cast int %tmp.12 to double ; [#uses=1] + %tmp.11 = call INT %time( INT* %secs ) ; [#uses=0] + %tmp.12 = load INT* %secs ; [#uses=1] + %tmp.13 = cast INT %tmp.12 to double ; [#uses=1] ret double %tmp.13 } """) @@ -49,8 +49,8 @@ extfunctions["%ll_time_clock"] = ((), """ internal fastcc double %ll_time_clock() { entry: - %tmp.0 = call int %clock( ) ; [#uses=1] - %tmp.1 = cast int %tmp.0 to double ; [#uses=1] + %tmp.0 = call INT %clock( ) ; [#uses=1] + %tmp.1 = cast INT %tmp.0 to double ; [#uses=1] %tmp.2 = div double %tmp.1, 1.000000e+06 ; [#uses=1] ret double %tmp.2 } @@ -63,19 +63,19 @@ %tmp.0 = call double %fmod( double %secs, double 1.000000e+00 ) ; [#uses=1] %tmp.2 = call double %floor( double %secs ) ; [#uses=1] %tmp.4 = getelementptr %struct.timeval* %t, int 0, uint 0 ; [#uses=1] - %tmp.6 = cast double %tmp.2 to int ; [#uses=1] - store int %tmp.6, int* %tmp.4 + %tmp.6 = cast double %tmp.2 to INT ; [#uses=1] + store INT %tmp.6, INT* %tmp.4 %tmp.7 = getelementptr %struct.timeval* %t, int 0, uint 1 ; [#uses=1] %tmp.9 = mul double %tmp.0, 1.000000e+06 ; [#uses=1] - %tmp.10 = cast double %tmp.9 to int ; [#uses=1] - store int %tmp.10, int* %tmp.7 - %tmp.11 = call int %select( int 0, %typedef.fd_set* null, %typedef.fd_set* null, %typedef.fd_set* null, %struct.timeval* %t ) ; [#uses=1] - %tmp.12 = setne int %tmp.11, 0 ; [#uses=2] - %tmp.13 = cast bool %tmp.12 to int ; [#uses=0] + %tmp.10 = cast double %tmp.9 to INT ; [#uses=1] + store INT %tmp.10, INT* %tmp.7 + %tmp.11 = call INT %select( INT 0, %typedef.fd_set* null, %typedef.fd_set* null, %typedef.fd_set* null, %struct.timeval* %t ) ; [#uses=1] + %tmp.12 = setne INT %tmp.11, 0 ; [#uses=2] + %tmp.13 = cast bool %tmp.12 to INT ; [#uses=0] br bool %tmp.12, label %then.1, label %return then.1: ; preds = %entry - ; XXX disabled for now: call void %RaiseSimpleException( int 1, sbyte* getelementptr ([16 x sbyte]* %.str_1, int 0, int 0) ) + ; XXX disabled for now: call void %RaiseSimpleException( INT 1, sbyte* getelementptr ([16 x sbyte]* %.str_1, INT 0, INT 0) ) ret void return: ; preds = %entry Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Mon Aug 22 21:35:07 2005 @@ -1,10 +1,10 @@ extdeclarations = """ declare ccc double %pow(double, double) declare ccc double %fmod(double, double) -declare ccc int %puts(sbyte*) -declare ccc int %strlen(sbyte*) -declare ccc int %strcmp(sbyte*, sbyte*) -declare ccc sbyte* %memset(sbyte*, int, uint) +declare ccc INT %puts(sbyte*) +declare ccc INT %strlen(sbyte*) +declare ccc INT %strcmp(sbyte*, sbyte*) +declare ccc sbyte* %memset(sbyte*, INT, UINT) %__print_debug_info = internal global bool false %__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" @@ -40,12 +40,12 @@ extfunctions["%string_to_RPyString"] = ((), """ internal fastcc %RPyString* %string_to_RPyString(sbyte* %s) { - %len = call ccc int %strlen(sbyte* %s) + %len = call ccc INT %strlen(sbyte* %s) %rpy = call fastcc %RPyString* %RPyString_New__Signed(int %len) %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* - call ccc sbyte* %strncpy(sbyte* %rpystr, sbyte* %s, int %len) + call ccc sbyte* %strncpy(sbyte* %rpystr, sbyte* %s, INT %len) ret %RPyString* %rpy } @@ -54,16 +54,16 @@ #abs functions extfunctions["%int_abs"] = ((), """ -internal fastcc int %int_abs(int %x) { +internal fastcc INT %int_abs(INT %x) { block0: - %cond1 = setge int %x, 0 + %cond1 = setge INT %x, 0 br bool %cond1, label %return_block, label %block1 block1: - %x2 = sub int 0, %x + %x2 = sub INT 0, %x br label %return_block return_block: - %result = phi int [%x, %block0], [%x2, %block1] - ret int %result + %result = phi INT [%x, %block0], [%x2, %block1] + ret INT %result } """) @@ -117,7 +117,7 @@ #note: XXX this hardcoded int32 minint value is used because of a pre llvm1.6 bug! int_ovf_test = """ - %cond2 = setne int %x, -2147483648 + %cond2 = setne INT %x, -2147483648 br bool %cond2, label %return_block, label %ovf ovf: call fastcc void %__prepare_OverflowError() @@ -129,10 +129,11 @@ for func_inst in "floordiv_zer:div mod_zer:rem".split(): func, inst = func_inst.split(':') - for type_ in "int uint".split(): + for prefix_type_ in "int:INT uint:UINT".split(): + prefix, type_ = prefix_type_.split(':') type_zer_test = zer_test % type_ - extfunctions["%%%(type_)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ -internal fastcc %(type_)s %%%(type_)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { + extfunctions["%%%(prefix)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ +internal fastcc %(type_)s %%%(prefix)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { %(type_zer_test)s %%z = %(inst)s %(type_)s %%x, %%y ret %(type_)s %%z @@ -144,26 +145,26 @@ #unary with OverflowError only extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc int %%int_neg_ovf(int %%x) { +internal fastcc INT %%int_neg_ovf(INT %%x) { block1: - %%x2 = sub int 0, %%x + %%x2 = sub INT 0, %%x %(int_ovf_test)s return_block: - ret int %%x2 + ret INT %%x2 } """ % locals()) extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc int %%int_abs_ovf(int %%x) { +internal fastcc INT %%int_abs_ovf(INT %%x) { block0: - %%cond1 = setge int %%x, 0 + %%cond1 = setge INT %%x, 0 br bool %%cond1, label %%return_block, label %%block1 block1: - %%x2 = sub int 0, %%x + %%x2 = sub INT 0, %%x %(int_ovf_test)s return_block: - %%result = phi int [%%x, %%block0], [%%x2, %%block1] - ret int %%result + %%result = phi INT [%%x, %%block0], [%%x2, %%block1] + ret INT %%result } """ % locals()) @@ -171,32 +172,32 @@ #binary with OverflowError only extfunctions["%int_add_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc int %%int_add_ovf(int %%x, int %%y) { - %%t = add int %%x, %%y +internal fastcc INT %%int_add_ovf(INT %%x, INT %%y) { + %%t = add INT %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_add_ovf checking - ret int %%t + ret INT %%t } """ % locals()) extfunctions["%int_sub_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc int %%int_sub_ovf(int %%x, int %%y) { - %%t = sub int %%x, %%y +internal fastcc INT %%int_sub_ovf(INT %%x, INT %%y) { + %%t = sub INT %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_sub_ovf checking - ret int %%t + ret INT %%t } """ % locals()) extfunctions["%int_mul_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc int %%int_mul_ovf(int %%x, int %%y) { - %%t = mul int %%x, %%y +internal fastcc INT %%int_mul_ovf(INT %%x, INT %%y) { + %%t = mul INT %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_mul_ovf checking - ret int %%t + ret INT %%t } """ % locals()) @@ -204,13 +205,13 @@ #binary with OverflowError and ValueError extfunctions["%int_lshift_ovf_val"] = (("%__prepare_OverflowError","%__prepare_ValueError"), """ -internal fastcc int %%int_lshift_ovf_val(int %%x, int %%y) { - %%yu = cast int %%y to ubyte - %%t = shl int %%x, ubyte %%yu +internal fastcc INT %%int_lshift_ovf_val(INT %%x, INT %%y) { + %%yu = cast INT %%y to ubyte + %%t = shl INT %%x, ubyte %%yu %(int_ovf_test)s return_block: ; XXX: TODO int_lshift_ovf_val checking VAL - ret int %%t + ret INT %%t } """ % locals()) @@ -218,42 +219,42 @@ #binary with OverflowError and ZeroDivisionError extfunctions["%int_floordiv_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ -internal fastcc int %%int_floordiv_ovf_zer(int %%x, int %%y) { +internal fastcc INT %%int_floordiv_ovf_zer(INT %%x, INT %%y) { %(int_zer_test)s - %%t = div int %%x, %%y + %%t = div INT %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_floordiv_ovf_zer checking - ret int %%t + ret INT %%t } """ % locals()) extfunctions["%int_mod_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ -internal fastcc int %%int_mod_ovf_zer(int %%x, int %%y) { +internal fastcc INT %%int_mod_ovf_zer(INT %%x, INT %%y) { %(int_zer_test)s - %%t = rem int %%x, %%y + %%t = rem INT %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_mod_ovf_zer checking - ret int %%t + ret INT %%t } """ % locals()) extfunctions["%main"] = (("%string_to_RPyString"), """ -int %main(int %argc, sbyte** %argv) { +INT %main(INT %argc, sbyte** %argv) { entry: - %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0) + %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(INT 0) br label %no_exit no_exit: - %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] - %i.0.0 = cast uint %indvar to int - %tmp.8 = getelementptr sbyte** %argv, uint %indvar + %indvar = phi UINT [ %indvar.next, %next_arg ], [ 0, %entry ] + %i.0.0 = cast UINT %indvar to INT + %tmp.8 = getelementptr sbyte** %argv, UINT %indvar %tmp.9 = load sbyte** %tmp.8 %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 - %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) - %cond = seteq int %res, 0 + %res = call ccc INT %strcmp(sbyte* %tmp.9, sbyte* %t) + %cond = seteq INT %res, 0 br bool %cond, label %debugging, label %not_debugging debugging: @@ -266,14 +267,14 @@ br label %next_arg next_arg: - %inc = add int %i.0.0, 1 - %tmp.2 = setlt int %inc, %argc - %indvar.next = add uint %indvar, 1 + %inc = add INT %i.0.0, 1 + %tmp.2 = setlt INT %inc, %argc + %indvar.next = add UINT %indvar, 1 br bool %tmp.2, label %no_exit, label %loopexit loopexit: - %ret = call fastcc int %entry_point(%structtype.list* %pypy_argv) - ret int %ret + %ret = call fastcc INT %entry_point(%structtype.list* %pypy_argv) + ret INT %ret } """) Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Mon Aug 22 21:35:07 2005 @@ -465,6 +465,8 @@ index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO) valuevar, valuetype = self.db.repr_argwithtype(op.args[2]) if valuetype != "void": + #Structure types require uint constants! + #see: http://llvm.cs.uiuc.edu/docs/LangRef.html#i_getelementptr self.codewriter.getelementptr(tmpvar, structtype, struct, ("uint", index)) self.codewriter.store(valuetype, valuevar, tmpvar) Modified: pypy/dist/pypy/translator/llvm2/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/structnode.py (original) +++ pypy/dist/pypy/translator/llvm2/structnode.py Mon Aug 22 21:35:07 2005 @@ -73,7 +73,7 @@ current = self.struct while isinstance(current, lltype.Struct): last_pos = len(current._names_without_voids()) - 1 - indices_to_array.append(("uint", last_pos)) + indices_to_array.append(("uint", last_pos)) #struct requires uint consts name = current._names_without_voids()[-1] current = current._flds[name] assert isinstance(current, lltype.Array) @@ -132,7 +132,8 @@ found = True break pos += 1 - + #Structure types require uint constants! + #see: http://llvm.cs.uiuc.edu/docs/LangRef.html#i_getelementptr return "getelementptr(%s* %s, int 0, uint %s)" %( self.get_typerepr(), self.get_ref(), Modified: pypy/dist/pypy/translator/llvm2/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/varsize.py (original) +++ pypy/dist/pypy/translator/llvm2/varsize.py Mon Aug 22 21:35:07 2005 @@ -1,31 +1,16 @@ from pypy.rpython.rstr import STR -# example for an array constructor in concrete llvm code: -# (thanks to chris lattner) -""" this function generates a LLVM function like the following: -%array = type { int, [0 x double] } -%array *%NewArray(int %len) { - ;; Get the offset of the 'len' element of the array from the null - ;; pointer. - %size = getelementptr %array* null, int 0, uint 1, %int %len - %usize = cast double* %size to uint - %ptr = malloc sbyte, uint %usize - %result = cast sbyte* %ptr to %array* - %arraylength = getelementptr %array* %result, int 0, uint 0 - store int %len, int* %arraylength - ret %array* %result -}""" - def write_constructor(db, codewriter, ref, constructor_decl, ARRAY, indices_to_array=(), atomicmalloc=False): #varsized arrays and structs look like this: - #Array: {int length , elemtype*} + #Array: {INT length , elemtype*} #Struct: {...., Array} # the following indices access the last element in the array elemtype = db.repr_type(ARRAY.OF) - lentype = db.get_machine_word() + word = lentype = db.get_machine_word() + uword = db.get_machine_uword() codewriter.openfunc(constructor_decl) @@ -37,12 +22,13 @@ elemindices = list(indices_to_array) + [("uint", 1), (lentype, "%actuallen")] codewriter.getelementptr("%size", ref + "*", "null", *elemindices) - codewriter.cast("%usize", elemtype + "*", "%size", "uint") + codewriter.cast("%usize", elemtype + "*", "%size", uword) codewriter.malloc("%ptr", "sbyte", "%usize", atomic=atomicmalloc) codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") if ARRAY is STR.chars: - codewriter.call('%memset_result', 'sbyte*', '%memset', ['%ptr', '0', '%usize',], ['sbyte*', 'int', 'uint'], cconv='ccc') + #XXX instead of memset we could probably just zero the hash and string terminator + codewriter.call('%memset_result', 'sbyte*', '%memset', ['%ptr', '0', '%usize',], ['sbyte*', word, uword], cconv='ccc') indices_to_arraylength = tuple(indices_to_array) + (("uint", 0),) # the following accesses the length field of the array @@ -50,16 +36,7 @@ "%result", *indices_to_arraylength) codewriter.store(lentype, "%len", "%arraylength") - - #if ARRAY is STR.chars: #(temp. disabled because we are moving memset from gc_malloc to here) - # # NUL the last element - # #lastelemindices = list(indices_to_array) + [("uint", 1), (lentype, "%len")] - # #codewriter.getelementptr("%terminator", - # # ref + "*", - # # "%result", - # # *lastelemindices) - # #codewriter.store(elemtype, 0, "%terminator") - + codewriter.ret(ref + "*", "%result") codewriter.closefunc() From hpk at codespeak.net Mon Aug 22 21:47:37 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 22 Aug 2005 21:47:37 +0200 (CEST) Subject: [pypy-svn] r16235 - pypy/branch/dist-newdoc/pypy/doc Message-ID: <20050822194737.89EFF27B41@code1.codespeak.net> Author: hpk Date: Mon Aug 22 21:47:36 2005 New Revision: 16235 Modified: pypy/branch/dist-newdoc/pypy/doc/news.txt Log: experimentally update news in the branch ... Modified: pypy/branch/dist-newdoc/pypy/doc/news.txt ============================================================================== --- pypy/branch/dist-newdoc/pypy/doc/news.txt (original) +++ pypy/branch/dist-newdoc/pypy/doc/news.txt Mon Aug 22 21:47:36 2005 @@ -9,16 +9,17 @@ .. _Python: http://www.python.org/doc/current/ref/ref.html .. _`more...`: architecture.html#mission-statement -Next PyPy Sprint in Heidelberg 22nd-29th August 2005 -====================================================== +Ongoing: PyPy Sprint in Heidelberg 22nd-29th August 2005 +========================================================== -The next PyPy sprint will take place at the Heidelberg University +The current PyPy sprint takes place at the Heidelberg University in Germany from 22nd August to 29th August (both days included). Its main focus is translation of the whole PyPy interpreter to a low level language and reaching 2.4.1 Python compliancy. -The goal of the sprint is to release a first self-contained PyPy-0.7 version. -To learn more see the `Heidelberg sprint announcement`_ or look at -the list of people_ that are expected to come. +The goal of the sprint is to release a first self-contained +PyPy-0.7 version. To learn more see the `Heidelberg sprint +announcement`_ or look at the list of people_ that are +expected to come. .. _people: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/heidelberg-people.html .. _`Heidelberg sprint announcement`: http://codespeak.net/pypy/index.cgi?extradoc/sprintinfo/Heidelberg-sprint.html From ericvrp at codespeak.net Mon Aug 22 21:50:47 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 22 Aug 2005 21:50:47 +0200 (CEST) Subject: [pypy-svn] r16236 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050822195047.52F0527B41@code1.codespeak.net> Author: ericvrp Date: Mon Aug 22 21:50:46 2005 New Revision: 16236 Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py Log: typos Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Mon Aug 22 21:50:46 2005 @@ -5,7 +5,7 @@ declare ccc INT %open(sbyte*, INT, INT) declare ccc INT %write(INT, sbyte*, INT) declare ccc INT %read(INT, sbyte*, INT) -declare ccc sbyte* %strncpy(sbyte*, sbyte*, int) +declare ccc sbyte* %strncpy(sbyte*, sbyte*, INT) declare ccc INT %isatty(INT) declare ccc INT %stat(sbyte*, [32 x INT]*) declare ccc INT %fstat(INT, [32 x INT]*) @@ -13,7 +13,7 @@ declare ccc INT %ftruncate(INT, INT) declare ccc sbyte* %getcwd(sbyte*, INT) -%errno = external global int +%errno = external global INT %__ll_os_getcwd = internal constant [12 x sbyte] c"getcwd.....\\00" %__ll_os_ftruncate = internal constant [12 x sbyte] c"ftruncate..\\00" Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Mon Aug 22 21:50:46 2005 @@ -41,7 +41,7 @@ extfunctions["%string_to_RPyString"] = ((), """ internal fastcc %RPyString* %string_to_RPyString(sbyte* %s) { %len = call ccc INT %strlen(sbyte* %s) - %rpy = call fastcc %RPyString* %RPyString_New__Signed(int %len) + %rpy = call fastcc %RPyString* %RPyString_New__Signed(INT %len) %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* From ericvrp at codespeak.net Mon Aug 22 21:59:21 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 22 Aug 2005 21:59:21 +0200 (CEST) Subject: [pypy-svn] r16237 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050822195921.BD39427B41@code1.codespeak.net> Author: ericvrp Date: Mon Aug 22 21:59:20 2005 New Revision: 16237 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py Log: * fixed exe buildig part for 64 bit architectures Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Mon Aug 22 21:59:20 2005 @@ -206,6 +206,9 @@ else: #assume 64 bit platform (x86-64?) #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)) + if exe_name: + cmds.append("gcc %s.c -c -O2 -fomit-frame-pointer" % (b,)) + cmds.append("gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) source_files.append("%s.c" % b) try: From cfbolz at codespeak.net Mon Aug 22 22:35:20 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 22 Aug 2005 22:35:20 +0200 (CEST) Subject: [pypy-svn] r16240 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050822203520.35EEB27B3E@code1.codespeak.net> Author: cfbolz Date: Mon Aug 22 22:35:18 2005 New Revision: 16240 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: first attempt at a semispace gc Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Mon Aug 22 22:35:18 2005 @@ -1,4 +1,5 @@ -from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL +from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy +from pypy.rpython.memory.lladdress import NULL from pypy.rpython.memory.support import AddressLinkedList from pypy.rpython.memory import lltypesimulation from pypy.rpython import lltype @@ -11,18 +12,18 @@ class MarkSweepGC(object): - _alloc_flavor_ = "" + _alloc_flavor_ = "raw" - def __init__(self, objectmodel, collect_every_bytes): + def __init__(self, objectmodel, start_heap_size): self.bytes_malloced = 0 - self.collect_every_bytes = collect_every_bytes + self.heap_size = start_heap_size #need to maintain a list of malloced objects, since we used the systems #allocator and can't walk the heap self.malloced_objects = AddressLinkedList() self.objectmodel = objectmodel def malloc(self, typeid, length=0): - if self.bytes_malloced > self.collect_every_bytes: + if self.bytes_malloced > self.heap_size: self.collect() size = self.objectmodel.fixed_size(typeid) if self.objectmodel.is_varsize(typeid): @@ -64,7 +65,6 @@ for i in range(len(offsets)): pointer = curr + offsets[i] objects.append(pointer.address[0]) - i += 1 if self.objectmodel.is_varsize(typeid): offset = self.objectmodel.varsize_offset_to_variable_part( typeid) @@ -72,24 +72,35 @@ offsets = self.objectmodel.varsize_offsets_to_gcpointers_in_var_part(typeid) itemlength = self.objectmodel.varsize_item_sizes(typeid) curr += offset - i = 0 for i in range(length): item = curr + itemlength * i for j in range(len(offsets)): objects.append((item + offsets[j]).address[0]) gc_info.signed[0] = 1 newmo = AddressLinkedList() + curr_heap_size = 0 + freed_size = 0 while 1: #sweep curr = self.malloced_objects.pop() if curr == NULL: break + typeid = curr.signed[1] + size = self.objectmodel.fixed_size(typeid) + if self.objectmodel.is_varsize(typeid): + length = (curr + self.size_gc_header() + self.objectmodel.varsize_offset_to_length(typeid)).signed[0] + size += length * self.objectmodel.varsize_item_sizes(typeid) if curr.signed[0] == 1: curr.signed[0] = 0 newmo.append(curr) + curr_heap_size += size + self.size_gc_header() else: + freed_size += size + self.size_gc_header() raw_free(curr) + print "free %s bytes. the heap is %s bytes." % (freed_size, curr_heap_size) free_non_gc_object(self.malloced_objects) self.malloced_objects = newmo + if curr_heap_size > self.heap_size: + self.heap_size = curr_heap_size def size_gc_header(self): return lltypesimulation.sizeof(lltype.Signed) * 2 @@ -98,3 +109,117 @@ addr.signed[0] = 0 addr.signed[1] = typeid + +class SemiSpaceGC(object): + _alloc_flavor_ = "raw" + + def __init__(self, objectmodel, space_size): + self.bytes_malloced = 0 + self.space_size = space_size + self.tospace = raw_malloc(space_size) + self.top_of_space = self.tospace + space_size + self.fromspace = raw_malloc(space_size) + self.free = self.tospace + self.objectmodel = objectmodel + + def malloc(self, typeid, length=0): + size = self.objectmodel.fixed_size(typeid) + if self.objectmodel.is_varsize(typeid): + size += length * self.objectmodel.varsize_item_sizes(typeid) + totalsize = size + self.size_gc_header() + if self.free + totalsize > self.top_of_space: + self.collect() + result = self.free + self.init_gc_object(result, typeid) + print "mallocing %s, size %s at %s" % (typeid, size, result) + self.free += totalsize + return result + self.size_gc_header() + + + def collect(self): + print "collecting" + self.fromspace, self.tospace = self.tospace, self.fromspace + self.top_of_space = self.tospace + self.space_size + roots = self.objectmodel.get_roots() + scan = self.free = self.tospace + while 1: + root = roots.pop() + if root == NULL: + break + print "root", root, root.address[0] + root.address[0] = self.copy(root.address[0]) + while scan < self.free: + curr = scan + self.size_gc_header() + self.trace_and_copy(curr) + scan += self.get_size(curr) + self.size_gc_header() + + def copy(self, obj): + if not self.fromspace <= obj < self.fromspace + self.space_size: + return self.copy_non_managed_obj(obj) + print "copying regularly", obj + if self.is_forwared(obj): + return self.get_forwarding_address(obj) + else: + newaddr = self.free + totalsize = self.get_size(obj) + self.size_gc_header() + raw_memcopy(obj - self.size_gc_header(), newaddr, totalsize) + self.free += totalsize + newobj = newaddr + self.size_gc_header() + self.set_forwarding_address(obj, newobj) + return newobj + + def copy_non_managed_obj(self, obj): #umph, PBCs, not really copy + print "copying nonmanaged", obj + #we have to do the tracing here because PBCs are not moved to tospace + self.trace_and_copy(obj) + return obj + + def trace_and_copy(self, obj): + gc_info = obj - self.size_gc_header() + typeid = gc_info.signed[1] + print "scanning", obj, typeid + offsets = self.objectmodel.offsets_to_gc_pointers(typeid) + for i in range(len(offsets)): + pointer = obj + offsets[i] + if pointer.address[0] != NULL: + pointer.address[0] = self.copy(pointer.address[0]) + if self.objectmodel.is_varsize(typeid): + offset = self.objectmodel.varsize_offset_to_variable_part( + typeid) + length = (obj + self.objectmodel.varsize_offset_to_length(typeid)).signed[0] + offsets = self.objectmodel.varsize_offsets_to_gcpointers_in_var_part(typeid) + itemlength = self.objectmodel.varsize_item_sizes(typeid) + for i in range(length): + item = obj + offset + itemlength * i + for j in range(len(offsets)): + pointer = item + offsets[j] + if pointer.address[0] != NULL: + pointer.address[0] = self.copy(pointer.address[0]) + + def is_forwared(self, obj): + return (obj - self.size_gc_header()).signed[1] == -1 + + def get_forwarding_address(self, obj): + return (obj - self.size_gc_header()).address[0] + + def set_forwarding_address(self, obj, newobj): + gc_info = obj - self.size_gc_header() + gc_info.signed[1] = -1 + gc_info.address[0] = newobj + + def get_size(self, obj): + typeid = (obj - self.size_gc_header()).signed[1] + size = self.objectmodel.fixed_size(typeid) + if self.objectmodel.is_varsize(typeid): + lenaddr = obj + self.objectmodel.varsize_offset_to_length(typeid) + length = lenaddr.signed[0] + size += length * self.objectmodel.varsize_item_sizes(typeid) + return size + + + def size_gc_header(self): + return lltypesimulation.sizeof(lltype.Signed) * 2 + + def init_gc_object(self, addr, typeid): + addr.signed[0] = 0 + addr.signed[1] = typeid Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Mon Aug 22 22:35:18 2005 @@ -35,11 +35,12 @@ fgcc.convert() return None +from pypy.rpython.memory.gc import MarkSweepGC, SemiSpaceGC +use_gc = MarkSweepGC def create_mark_sweep_gc(llinterp, flowgraphs): from pypy.rpython.memory.gcwrapper import GcWrapper, LLInterpObjectModel - from pypy.rpython.memory.gc import MarkSweepGC #XXX hackish: we need the gc before the object model is ready - gc = MarkSweepGC(None, 4096) + gc = use_gc(None, 4096) fgcc = FlowGraphConstantConverter(flowgraphs, gc) fgcc.convert() om = LLInterpObjectModel(llinterp, fgcc.cvter.types, Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Mon Aug 22 22:35:18 2005 @@ -59,24 +59,31 @@ return typeid def is_varsize(self, typeid): + assert typeid >= 0 return self._is_varsize[typeid] def offsets_to_gc_pointers(self, typeid): + assert typeid >= 0 return self._offsets_to_gc_pointers[typeid] def fixed_size(self, typeid): + assert typeid >= 0 return self._fixed_size[typeid] def varsize_item_sizes(self, typeid): + assert typeid >= 0 return self._varsize_item_sizes[typeid] def varsize_offset_to_variable_part(self, typeid): + assert typeid >= 0 return self._varsize_offset_to_variable_part[typeid] def varsize_offset_to_length(self, typeid): + assert typeid >= 0 return self._varsize_offset_to_length[typeid] def varsize_offsets_to_gcpointers_in_var_part(self, typeid): + assert typeid >= 0 return self._varsize_offsets_to_gcpointers_in_var_part[typeid] def get_roots(self): @@ -84,7 +91,9 @@ if self.pseudo_root_pointers != NULL: raw_free(self.pseudo_root_pointers) self.roots = self.llinterp.find_roots() + self.constantroots - print "found:", self.roots + self.roots = [r for r in self.roots + if isinstance(r._TYPE.TO, + (lltype.Struct, lltype.Array))] if len(self.roots) == 0: self.pseudo_root_pointers = NULL else: Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Mon Aug 22 22:35:18 2005 @@ -3,7 +3,7 @@ from pypy.annotation import model as annmodel from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython.rtyper import RPythonTyper -from pypy.rpython.memory.gc import GCError, MarkSweepGC +from pypy.rpython.memory.gc import GCError, MarkSweepGC, SemiSpaceGC from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL from pypy.rpython.memory.simulator import MemorySimulatorError @@ -58,8 +58,16 @@ variables.address[1] = gc.malloc(0) variables.address[2] = gc.malloc(0) variables.address[3] = gc.malloc(0) + variables.address[0].signed[0] = 0 + variables.address[1].signed[0] = 1 + variables.address[2].signed[0] = 2 + variables.address[3].signed[0] = 3 print "roots", roots gc.collect() #does not crash + assert variables.address[0].signed[0] == 0 + assert variables.address[1].signed[0] == 1 + assert variables.address[2].signed[0] == 2 + assert variables.address[3].signed[0] == 3 addr = gc.malloc(0) addr.signed[0] = 1 print "roots", roots @@ -70,6 +78,8 @@ variables.address[0].address[1] = NULL print "roots", roots gc.collect() #does not crash + assert variables.address[0].address[0] == variables.address[1] + assert variables.address[0].address[1] == NULL addr0 = gc.malloc(1) addr0.address[1] = NULL addr1 = gc.malloc(1) @@ -83,7 +93,6 @@ gc.collect() py.test.raises(MemorySimulatorError, "addr0.signed[0]") py.test.raises(MemorySimulatorError, "addr1.signed[0]") - py.test.raises(MemorySimulatorError, "addr2.signed[0]") def test_llinterp_lists(self): curr = simulator.current_size @@ -137,3 +146,87 @@ res = interpret(concat, [100]) assert res == concat(100) assert simulator.current_size - curr < 16000 + + +class TestSemiSpaceGC(object): + def setup_class(cls): + gclltype.use_gc = SemiSpaceGC + cls.old = gclltype.use_gc + def teardown_class(cls): + gclltype.use_gc = cls.old + + def test_simple(self): + variables = raw_malloc(4 * INT_SIZE) + roots = [variables + i * INT_SIZE for i in range(4)] + layout0 = [] #int + layout1 = [0, INT_SIZE] #(ptr, ptr) + om = PseudoObjectModel(roots, {0: layout0, 1: layout1}, {0: INT_SIZE, 1: 2 * INT_SIZE}) + gc = SemiSpaceGC(om, 2 ** 16) + variables.address[0] = gc.malloc(0) + variables.address[1] = gc.malloc(0) + variables.address[2] = gc.malloc(0) + variables.address[3] = gc.malloc(0) + variables.address[0].signed[0] = 0 + variables.address[1].signed[0] = 1 + variables.address[2].signed[0] = 2 + variables.address[3].signed[0] = 3 + print "roots", roots + gc.collect() #does not crash + assert variables.address[0].signed[0] == 0 + assert variables.address[1].signed[0] == 1 + assert variables.address[2].signed[0] == 2 + assert variables.address[3].signed[0] == 3 + addr = gc.malloc(0) + addr.signed[0] = 1 + print "roots", roots + gc.collect() +## py.test.raises(MemorySimulatorError, "addr.signed[0]") + variables.address[0] = gc.malloc(1) + variables.address[0].address[0] = variables.address[1] + variables.address[0].address[1] = NULL + print "roots", roots + gc.collect() #does not crash + assert variables.address[0].address[0] == variables.address[1] + assert variables.address[0].address[1] == NULL + addr0 = gc.malloc(1) + addr0.address[1] = NULL + addr1 = gc.malloc(1) + addr1.address[0] = addr1.address[1] = NULL + addr0.address[0] = addr1 + addr2 = variables.address[1] + print "addr0, addr1, addr2 =", addr0, addr1, addr2 + variables.address[1] == NULL + variables.address[0].address[0] = NULL + print "roots", roots + gc.collect() + + def test_llinterp_lists(self): + curr = simulator.current_size + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = [1] * 10 + j = 0 + while j < 20: + j += 1 + a.append(j) + res = interpret(malloc_a_lot, []) + assert simulator.current_size - curr < 16000 + print "size before: %s, size after %s" % (curr, simulator.current_size) + + def test_llinterp_tuples(self): + curr = simulator.current_size + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = (1, 2, i) + b = [a] * 10 + j = 0 + while j < 20: + j += 1 + b.append((1, j, i)) + res = interpret(malloc_a_lot, []) + assert simulator.current_size - curr < 16000 + print "size before: %s, size after %s" % (curr, simulator.current_size) From ale at codespeak.net Tue Aug 23 10:15:28 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 10:15:28 +0200 (CEST) Subject: [pypy-svn] r16242 - pypy/dist/pypy/module/_codecs Message-ID: <20050823081528.ACEBB27B3B@code1.codespeak.net> Author: ale Date: Tue Aug 23 10:15:27 2005 New Revision: 16242 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: (Jakob, Anders) test_codecs pass The logic for partial decoding of utf-8 and utf-16 was reversed Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Tue Aug 23 10:15:27 2005 @@ -161,10 +161,13 @@ v = s[1:-1] return v,len(v) -def utf_8_decode( data,errors='strict',final=None): +def utf_8_decode( data,errors='strict',final=0): """None """ - res,consumed = PyUnicode_DecodeUTF8Stateful(data, len(data), errors, final) + consumed = len(data) + if final: + consumed = 0 + res,consumed = PyUnicode_DecodeUTF8Stateful(data, len(data), errors, consumed) res = u''.join(res) return res, consumed @@ -199,7 +202,10 @@ def utf_16_decode( data,errors='strict',final=None): """None """ - res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors) + consumed = len(data) + if final: + consumed = 0 + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'native',consumed) res = ''.join(res) return res, consumed @@ -287,7 +293,10 @@ bm = 'little' else: bm = 'big' - res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,bm) + consumed = len(data) + if final: + consumed = 0 + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,bm,consumed) res = ''.join(res) return res, consumed, byteorder @@ -416,14 +425,20 @@ def utf_16_le_decode( data,errors='strict',byteorder=0, final = 0): """None """ - res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little') + consumed = len(data) + if final: + consumed = 0 + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'little',consumed) res = u''.join(res) return res, consumed def utf_16_be_decode( data,errors='strict',byteorder=0, final = 0): """None """ - res, consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big') + consumed = len(data) + if final: + consumed = 0 + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'big',consumed) res = u''.join(res) return res, consumed @@ -1114,7 +1129,7 @@ endinpos = size res = unicode_call_errorhandler( errors, "utf8", errmsg, - s, startinpos, endinpos) + s, startinpos, endinpos) p += res[0] pos = res[1] if n == 0: @@ -1249,7 +1264,7 @@ if (consumed): consumed = pos - return p, consumed + return p, pos # consumed def PyUnicode_EncodeUTF8(s,size,errors): From hpk at codespeak.net Tue Aug 23 11:19:17 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 11:19:17 +0200 (CEST) Subject: [pypy-svn] r16244 - pypy/extradoc/sprintinfo Message-ID: <20050823091917.54D0927B47@code1.codespeak.net> Author: hpk Date: Tue Aug 23 11:19:16 2005 New Revision: 16244 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: update today's planning Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Tue Aug 23 11:19:16 2005 @@ -37,7 +37,7 @@ to reflect the 0.7 situation - update getting_started.txt to reflect the 0.7 release and include instruction on how to translate - - possibly streamline the tool chain + - possibly streamline the tool chain (for genc/llvm) - do we have an easy-to-explain tool chain working for win32? - maybe globally use "bytecode interpreter" instead of "plain interpreter" - write 0.7.0 release announcement + README @@ -59,6 +59,8 @@ Translation - Finish GIL-based threading: backend support, fix bugs? (arigo, rxe) + + adding backend support is in-progress - (Decide whether to try to implement other threading locking policies) (probably not at the moment, let's see) @@ -66,18 +68,43 @@ - Isolate refcounting in genc, and (cfbolz, pedronis) have an option to enable and use Boehm instead -2.4.1 Compliance (arre, tismer) + in progress of adding GCPolicy that encapsulates refcounting + and is to be called from all places that now hardcode refcounting. + +2.4.1 Compliance (arre, tismer):: - Recategorize the tests in core/non-core ( = language compliancy) + 41 current-core tests should not be in core, + 11 current-non-core tests should be in core + 5 are about threading (should be core?) - test_unicode, test_codecs (ale, jacob) + test_unicode has one remaining error involving + eval(unicode) which means that compile(unicode) does not work + currently. (see issue in the tracker, ludovic will try to look + into this briefly) - Fix/adjust/prioritize compliance test problems + done: fixed binascii problems. + - (tismer) in-progress: speeding up compilation on the + translated pypy version by doing an external cpython-invocation + to produce the code object. - Some other "non-core" tests revealing real bugs/problems? -Compiler/Parser + - from wednesday morning on most of us should work + on compliancy related issues + + - (holger) try to fix the problem that you have to be in + 2.4.1/test in order to successfully run tests + + - NOTE: pypy-dist/lib-python/failure_list.txt + contains ongoing anaylsis/Status for compliancy tests! + +Compiler/Parser:: - Fix bugs, missing features (some cause compliance regressions) - Work on making the compiler interp-level st->ast mostly done, should go into the release (ludal, nik) + integrated with a runtime option + need to fix astcompiler ast->bytecode is not going to be done for the release (kept at app-level) @@ -89,30 +116,34 @@ inputs that are a single string are considered docstrings (also single unicode strings are considered docstrings) -* Built-in modules + +Built-in modules:: - Do we still miss important os.* functionality? - errno (easy for now) - - Enable our own array/_sre when translating (try with the current - _sre and its interp-level parts, otherwise just use the app-level - one) + - Enable our own array/_sre when translating + (try with the current _sre and its interp-level parts, + otherwise just use the app-level + one) (nik) in progress (trying to get '_sre' to translate) - (Review builtin modules again to see if we missed something) - 'math' must be finished (math.log()) -Fix/garden issues for the release in the tracker +Fix/garden issues for the release in the tracker:: - Go over the issues in the tracker: close, postpone or fix them as needed for the release - Review Hildes_to_Heidel.txt contents too -LLVM backend +LLVM backend:: - Improvement work to stabilize and match genc - (Try to share code with genc?) -GC +GC:: - Complete SoC GC framework (cfbolz) + in-progress: two more nights or so. + - (Start to think how/what is still missing to leverage it for Phase 2) - (related: isolating refcounting) From ac at codespeak.net Tue Aug 23 11:35:11 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 23 Aug 2005 11:35:11 +0200 (CEST) Subject: [pypy-svn] r16245 - pypy/dist/lib-python Message-ID: <20050823093511.2995E27B53@code1.codespeak.net> Author: ac Date: Tue Aug 23 11:35:10 2005 New Revision: 16245 Modified: pypy/dist/lib-python/conftest.py Log: Reclasssify tests as core/non-core. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Aug 23 11:35:10 2005 @@ -361,9 +361,9 @@ RegrTest('test__locale.py', enabled=True), RegrTest('test_aepack.py', enabled=False), RegrTest('test_al.py', enabled=False, dumbtest=1), - RegrTest('test_anydbm.py', enabled=True, core=True), + RegrTest('test_anydbm.py', enabled=True), RegrTest('test_applesingle.py', enabled=False), - RegrTest('test_array.py', enabled=True), + RegrTest('test_array.py', enabled=True, core=True), RegrTest('test_asynchat.py', enabled=False), RegrTest('test_atexit.py', enabled=False, dumbtest=1, core=True), RegrTest('test_audioop.py', enabled=False, dumbtest=1), @@ -385,22 +385,22 @@ RegrTest('test_bufio.py', enabled=False, dumbtest=1, core=True), RegrTest('test_builtin.py', enabled=True, core=True), RegrTest('test_bz2.py', enabled=False), - RegrTest('test_calendar.py', enabled=True, core=True), + RegrTest('test_calendar.py', enabled=True), RegrTest('test_call.py', enabled=True, core=True), RegrTest('test_capi.py', enabled=False, dumbtest=1), RegrTest('test_cd.py', enabled=False, dumbtest=1), - RegrTest('test_cfgparser.py', enabled=False, core=True), + RegrTest('test_cfgparser.py', enabled=False), #rev 10840: Uncaught interp-level exception: #File "pypy/objspace/std/fake.py", line 133, in setfastscope #raise UnwrapError('calling %s: %s' % (self.code.cpy_callable, e)) #pypy.objspace.std.model.UnwrapError: calling : cannot unwrap > - RegrTest('test_cgi.py', enabled=True, core=True), - RegrTest('test_charmapcodec.py', enabled=True), + RegrTest('test_cgi.py', enabled=True), + RegrTest('test_charmapcodec.py', enabled=True, core=True), RegrTest('test_cl.py', enabled=False, dumbtest=1), RegrTest('test_class.py', enabled=False, oldstyle=True, core=True), RegrTest('test_cmath.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_codeccallbacks.py', enabled=False), + RegrTest('test_codeccallbacks.py', enabled=False, core=True), #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser RegrTest('test_codecencodings_cn.py', enabled=False), RegrTest('test_codecencodings_hk.py', enabled=False), @@ -414,14 +414,14 @@ RegrTest('test_codecmaps_kr.py', enabled=False), RegrTest('test_codecmaps_tw.py', enabled=False), - RegrTest('test_codecs.py', enabled=False), + RegrTest('test_codecs.py', enabled=False, core=True), #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser RegrTest('test_codeop.py', enabled=True, core=True), RegrTest('test_coercion.py', enabled=False, oldstyle=True, core=True), # needed changes because our exceptions are new-style and so have a different str(.) behavior - RegrTest('test_colorsys.py', enabled=True, core=True), + RegrTest('test_colorsys.py', enabled=True), RegrTest('test_commands.py', enabled=True), RegrTest('test_compare.py', enabled=True, oldstyle=True, core=True), RegrTest('test_compile.py', enabled=True, core=True), @@ -430,8 +430,8 @@ #rev 10840: at least one test fails, after several hours I gave up waiting for the rest RegrTest('test_contains.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_cookie.py', enabled=False, core=True), - RegrTest('test_cookielib.py', enabled=False, core=True), + RegrTest('test_cookie.py', enabled=False), + RegrTest('test_cookielib.py', enabled=False), RegrTest('test_copy.py', enabled=True, core=True), RegrTest('test_copy_reg.py', enabled=True, core=True), RegrTest('test_cpickle.py', enabled=False, core=True), @@ -440,23 +440,23 @@ #rev 10840: ImportError: _csv RegrTest('test_curses.py', enabled=False, dumbtest=1), - RegrTest('test_datetime.py', enabled=True, core=True), + RegrTest('test_datetime.py', enabled=True), RegrTest('test_dbm.py', enabled=False, dumbtest=1), - RegrTest('test_decimal.py', enabled=True, core=True), + RegrTest('test_decimal.py', enabled=True), RegrTest('test_decorators.py', enabled=True, core=True), RegrTest('test_deque.py', enabled=True, core=True), RegrTest('test_descr.py', enabled=False, core=True, oldstyle=True), RegrTest('test_descrtut.py', enabled=False, core=True, oldstyle=True), RegrTest('test_dict.py', enabled=True, core=True), - RegrTest('test_difflib.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_difflib.py', enabled=True, dumbtest=1), RegrTest('test_dircache.py', enabled=True, core=True), RegrTest('test_dis.py', enabled=True), RegrTest('test_distutils.py', enabled=True, core=True), RegrTest('test_dl.py', enabled=False, dumbtest=1), RegrTest('test_doctest.py', enabled=True, core=True), RegrTest('test_doctest2.py', enabled=True, core=True), - RegrTest('test_dumbdbm.py', enabled=True, core=True), + RegrTest('test_dumbdbm.py', enabled=True), RegrTest('test_dummy_thread.py', enabled=True, core=True), RegrTest('test_dummy_threading.py', enabled=True, dumbtest=1, core=True), RegrTest('test_email.py', enabled=False), @@ -484,7 +484,7 @@ RegrTest('test_future1.py', enabled=True, dumbtest=1, core=True), RegrTest('test_future2.py', enabled=True, dumbtest=1, core=True), RegrTest('test_future3.py', enabled=True, core=True), - RegrTest('test_gc.py', enabled=False, dumbtest=1), + RegrTest('test_gc.py', enabled=False, dumbtest=1, core=True), RegrTest('test_gdbm.py', enabled=False, dumbtest=1), RegrTest('test_generators.py', enabled=False, core=True), #rev 10840: 30 of 152 tests fail @@ -512,15 +512,15 @@ RegrTest('test_hash.py', enabled=True, core=True), RegrTest('test_heapq.py', enabled=True, core=True), RegrTest('test_hexoct.py', enabled=True, core=True), - RegrTest('test_hmac.py', enabled=True, core=True), + RegrTest('test_hmac.py', enabled=True), RegrTest('test_hotshot.py', enabled=False), #rev 10840: ImportError: _hotshot - RegrTest('test_htmllib.py', enabled=True, core=True), - RegrTest('test_htmlparser.py', enabled=True, core=True), - RegrTest('test_httplib.py', enabled=True, core=True), + RegrTest('test_htmllib.py', enabled=True), + RegrTest('test_htmlparser.py', enabled=True), + RegrTest('test_httplib.py', enabled=True), RegrTest('test_imageop.py', enabled=False, dumbtest=1), - RegrTest('test_imaplib.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_imaplib.py', enabled=True, dumbtest=1), RegrTest('test_imgfile.py', enabled=False, dumbtest=1), RegrTest('test_imp.py', enabled=False, core="maybe"), RegrTest('test_import.py', enabled=False, dumbtest=1, core="possibly"), @@ -550,17 +550,17 @@ RegrTest('test_math.py', enabled=False, core=True, usemodules=['math']), RegrTest('test_md5.py', enabled=False), RegrTest('test_mhlib.py', enabled=True), - RegrTest('test_mimetools.py', enabled=True, core=True), - RegrTest('test_mimetypes.py', enabled=True, core=True), + RegrTest('test_mimetools.py', enabled=True), + RegrTest('test_mimetypes.py', enabled=True), RegrTest('test_MimeWriter.py', enabled=True, core=True), RegrTest('test_minidom.py', enabled=False, dumbtest=1), RegrTest('test_mmap.py', enabled=False), RegrTest('test_module.py', enabled=False, dumbtest=1, core=True), RegrTest('test_multibytecodec.py', enabled=True, core=True), RegrTest('test_multibytecodec_support.py', enabled=True, core=True), - RegrTest('test_multifile.py', enabled=True, core=True), + RegrTest('test_multifile.py', enabled=True), RegrTest('test_mutants.py', enabled=False, dumbtest=1, core="possibly"), - RegrTest('test_netrc.py', enabled=True, core=True), + RegrTest('test_netrc.py', enabled=True), RegrTest('test_new.py', enabled=False, core=True, oldstyle=True), RegrTest('test_nis.py', enabled=False), RegrTest('test_normalization.py', enabled=False), @@ -569,19 +569,19 @@ RegrTest('test_openpty.py', enabled=False), RegrTest('test_operations.py', enabled=False, core=True), RegrTest('test_operator.py', enabled=True, core=True), - RegrTest('test_optparse.py', enabled=False, core="maybe"), + RegrTest('test_optparse.py', enabled=False), # this test fails because it expects that PyPy's builtin # functions act as if they are staticmethods that can be put # on classes and don't get bound etc.pp. RegrTest('test_os.py', enabled=True, core=True), RegrTest('test_ossaudiodev.py', enabled=False), - RegrTest('test_parser.py', enabled=False), + RegrTest('test_parser.py', enabled=False, core=True), #rev 10840: 18 of 18 tests fail RegrTest('test_peepholer.py', enabled=True), RegrTest('test_pep247.py', enabled=False, dumbtest=1), - RegrTest('test_pep263.py', enabled=True, dumbtest=1), + RegrTest('test_pep263.py', enabled=True, dumbtest=1, core=True), RegrTest('test_pep277.py', enabled=False), # XXX this test is _also_ an output test, damn it # seems to be the only one that invokes run_unittest @@ -598,14 +598,14 @@ RegrTest('test_posix.py', enabled=True), RegrTest('test_posixpath.py', enabled=True), RegrTest('test_pow.py', enabled=True, core=True), - RegrTest('test_pprint.py', enabled=True, core=True), + RegrTest('test_pprint.py', enabled=True), RegrTest('test_profile.py', enabled=True, core="maybe"), RegrTest('test_profilehooks.py', enabled=True, core=True), RegrTest('test_pty.py', enabled=False), RegrTest('test_pwd.py', enabled=False), #rev 10840: ImportError: pwd - RegrTest('test_pyclbr.py', enabled=False, core="maybe"), + RegrTest('test_pyclbr.py', enabled=False), RegrTest('test_pyexpat.py', enabled=False), RegrTest('test_queue.py', enabled=False, dumbtest=1), RegrTest('test_quopri.py', enabled=True), @@ -616,7 +616,7 @@ #gen = random.WichmannHill() #AttributeError: 'module' object has no attribute 'WichmannHill' - RegrTest('test_re.py', enabled=True), + RegrTest('test_re.py', enabled=True, core=True), RegrTest('test_regex.py', enabled=False), RegrTest('test_repr.py', enabled=False, core="ill-defined"), @@ -624,25 +624,24 @@ #'' != '' RegrTest('test_resource.py', enabled=False), - RegrTest('test_rfc822.py', enabled=True, core=True), + RegrTest('test_rfc822.py', enabled=True), RegrTest('test_rgbimg.py', enabled=False), RegrTest('test_richcmp.py', enabled=False, core=True), #rev 10840: 1 of 11 test fails. The failing one had an infinite recursion. - RegrTest('test_robotparser.py', enabled=True, core=True), + RegrTest('test_robotparser.py', enabled=True), RegrTest('test_sax.py', enabled=False, dumbtest=1), RegrTest('test_scope.py', enabled=True, core=True), RegrTest('test_scriptpackages.py', enabled=False), RegrTest('test_select.py', enabled=False, dumbtest=1), RegrTest('test_set.py', enabled=True, core=True), - RegrTest('test_sets.py', enabled=True, core=True), - RegrTest('test_set.py', enabled=True, core=True), - RegrTest('test_sgmllib.py', enabled=True, core=True), + RegrTest('test_sets.py', enabled=True), + RegrTest('test_sgmllib.py', enabled=True), RegrTest('test_sha.py', enabled=True), # one test is taken out (too_slow_test_case_3), rest passses - RegrTest('test_shelve.py', enabled=True, core=True), - RegrTest('test_shlex.py', enabled=True, core=True), - RegrTest('test_shutil.py', enabled=True, core=True), + RegrTest('test_shelve.py', enabled=True), + RegrTest('test_shlex.py', enabled=True), + RegrTest('test_shutil.py', enabled=True), RegrTest('test_signal.py', enabled=False), RegrTest('test_site.py', enabled=False, core=True), # Needs non-faked codecs. @@ -679,22 +678,22 @@ RegrTest('test_syntax.py', enabled=True, core=True), RegrTest('test_sys.py', enabled=True, core=True), RegrTest('test_tcl.py', enabled=False), - RegrTest('test_tarfile.py', enabled=False, core="possibly"), + RegrTest('test_tarfile.py', enabled=False), #rev 10840: 13 of 13 test fail - RegrTest('test_tempfile.py', enabled=False, core=True), + RegrTest('test_tempfile.py', enabled=False), # tempfile does: class ... unlink = _os.unlink!!! #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser - RegrTest('test_textwrap.py', enabled=True, core=True), - RegrTest('test_thread.py', enabled=False), - RegrTest('test_threaded_import.py', enabled=False), - RegrTest('test_threadedtempfile.py', enabled=False), + RegrTest('test_textwrap.py', enabled=True), + RegrTest('test_thread.py', enabled=False, core=True), + RegrTest('test_threaded_import.py', enabled=False, core=True), + RegrTest('test_threadedtempfile.py', enabled=False, core=True), #rev 10840: ImportError: thread - RegrTest('test_threading.py', enabled=False, dumbtest=1), + RegrTest('test_threading.py', enabled=False, dumbtest=1, core=True), #rev 10840: ImportError: thread - RegrTest('test_threading_local.py', enabled=False, dumbtest=1), + RegrTest('test_threading_local.py', enabled=False, dumbtest=1, core=True), RegrTest('test_threadsignals.py', enabled=False, dumbtest=1), RegrTest('test_time.py', enabled=True, core=True), @@ -702,7 +701,7 @@ #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser RegrTest('test_timing.py', enabled=False, dumbtest=1), - RegrTest('test_tokenize.py', enabled=False, core=True), + RegrTest('test_tokenize.py', enabled=False), RegrTest('test_trace.py', enabled=True, core=True), RegrTest('test_traceback.py', enabled=False, core=True), #rev 10840: 2 of 2 tests fail @@ -716,18 +715,18 @@ RegrTest('test_ucn.py', enabled=False), RegrTest('test_unary.py', enabled=True, core=True), - RegrTest('test_unicode.py', enabled=False), #, core=True), + RegrTest('test_unicode.py', enabled=False, core=True), RegrTest('test_unicode_file.py', enabled=False), RegrTest('test_unicodedata.py', enabled=False), RegrTest('test_unittest.py', enabled=True, core=True), RegrTest('test_univnewlines.py', enabled=True, core=True), RegrTest('test_unpack.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_urllib.py', enabled=True, core=True), - RegrTest('test_urllib2.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_urllib.py', enabled=True), + RegrTest('test_urllib2.py', enabled=True, dumbtest=1), RegrTest('test_urllib2net.py', enabled=True), RegrTest('test_urllibnet.py', enabled=False), # try to understand failure!!! - RegrTest('test_urlparse.py', enabled=True, core=True), + RegrTest('test_urlparse.py', enabled=True), RegrTest('test_userdict.py', enabled=True, core=True), RegrTest('test_userlist.py', enabled=True, core=True), RegrTest('test_userstring.py', enabled=False, core=True), @@ -736,10 +735,10 @@ RegrTest('test_warnings.py', enabled=True, core=True), RegrTest('test_wave.py', enabled=False, dumbtest=1), - RegrTest('test_weakref.py', enabled=False), + RegrTest('test_weakref.py', enabled=False, core=True), #rev 10840: ImportError: _weakref - RegrTest('test_whichdb.py', enabled=True, core=True), + RegrTest('test_whichdb.py', enabled=True), RegrTest('test_winreg.py', enabled=False), RegrTest('test_winsound.py', enabled=False), RegrTest('test_xmllib.py', enabled=False), @@ -749,7 +748,7 @@ RegrTest('test_xpickle.py', enabled=False), RegrTest('test_xrange.py', enabled=True, core=True), RegrTest('test_zipfile.py', enabled=False, dumbtest=1), - RegrTest('test_zipimport.py', enabled=False), + RegrTest('test_zipimport.py', enabled=False, core=True), #rev 10840: ImportError: zlib RegrTest('test_zlib.py', enabled=False), From nik at codespeak.net Tue Aug 23 12:09:44 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 12:09:44 +0200 (CEST) Subject: [pypy-svn] r16247 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050823100944.9842D27B43@code1.codespeak.net> Author: nik Date: Tue Aug 23 12:09:42 2005 New Revision: 16247 Added: pypy/dist/lib-python/modified-2.4.1/test/test_xrange.py - copied, changed from r16243, pypy/dist/lib-python/2.4.1/test/test_xrange.py Log: disabled xrange OverflowError tests because PyPy can handle long arguments to xrange just well. test passes now. From ale at codespeak.net Tue Aug 23 12:17:46 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 12:17:46 +0200 (CEST) Subject: [pypy-svn] r16248 - pypy/dist/lib-python Message-ID: <20050823101746.11B3627B34@code1.codespeak.net> Author: ale Date: Tue Aug 23 12:17:40 2005 New Revision: 16248 Modified: pypy/dist/lib-python/failure_list.txt Log: update test_exceptions test_syntax Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Tue Aug 23 12:17:40 2005 @@ -1,6 +1,20 @@ test_pprint fails because "dict.__repr__ is dict.__repr__" equals False +test_syntax fails because "del f()" produces SyntaxError with message = + "can't assign to function call" instead of "can't delete function call". + The test is for "delete" to be in the message + +test_exceptions fails with exception message mismatches: + 'continue' not allowed inside 'finally' clause (, 5) + instead oof 'continue' not supported inside 'finally' clause + and + 'continue' outside loop (, 2) + instead of 'continue' not properly in loop + and + 'continue' outside loop (, 1) + instead of 'continue' not properly in loop + test_import fails because os.open is case insensitive (at least on Mac os X) From nik at codespeak.net Tue Aug 23 12:20:23 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 12:20:23 +0200 (CEST) Subject: [pypy-svn] r16250 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050823102023.869E927B34@code1.codespeak.net> Author: nik Date: Tue Aug 23 12:20:22 2005 New Revision: 16250 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_xrange.py Log: ValueError isn't raised either on 64 bit machines. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_xrange.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_xrange.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_xrange.py Tue Aug 23 12:20:22 2005 @@ -56,12 +56,12 @@ #self.assertRaises(OverflowError, xrange, 0, 2*sys.maxint) r = xrange(-sys.maxint, sys.maxint, 2) - if sys.maxint > 0x7fffffff: - # XXX raising ValueError is less than ideal, but this can't - # be fixed until range_length() returns a long in rangeobject.c - self.assertRaises(ValueError, len, r) - else: - self.assertEqual(len(r), sys.maxint) + #f sys.maxint > 0x7fffffff: + # # XXX raising ValueError is less than ideal, but this can't + # # be fixed until range_length() returns a long in rangeobject.c + # self.assertRaises(ValueError, len, r) + #else: + self.assertEqual(len(r), sys.maxint) #self.assertRaises(OverflowError, xrange, -sys.maxint-1, sys.maxint, 2) def test_main(): From nik at codespeak.net Tue Aug 23 12:41:33 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 12:41:33 +0200 (CEST) Subject: [pypy-svn] r16253 - pypy/dist/pypy/annotation Message-ID: <20050823104133.354E727B36@code1.codespeak.net> Author: nik Date: Tue Aug 23 12:41:31 2005 New Revision: 16253 Modified: pypy/dist/pypy/annotation/bookkeeper.py Log: fixed typo in exception message Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Tue Aug 23 12:41:31 2005 @@ -637,7 +637,7 @@ try: args.fixedunpack(0) except ValueError: - raise Exception, "no __init__ found in %r" % (cls,) + raise Exception, "no __init__ found in %r" % (classdef.cls,) return s_instance assert isinstance(func, FunctionType), "[%s] expected user-defined function, got %r" % (self.whereami(), func) From hpk at codespeak.net Tue Aug 23 12:57:43 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 12:57:43 +0200 (CEST) Subject: [pypy-svn] r16254 - pypy/extradoc/website Message-ID: <20050823105743.EB4BA27B3D@code1.codespeak.net> Author: hpk Date: Tue Aug 23 12:57:43 2005 New Revision: 16254 Added: pypy/extradoc/website/ pypy/extradoc/website/confrest.py - copied unchanged from r16235, pypy/branch/dist-newdoc/pypy/doc/confrest.py pypy/extradoc/website/conftest.py - copied unchanged from r16235, pypy/branch/dist-newdoc/pypy/doc/conftest.py pypy/extradoc/website/contact.txt - copied unchanged from r16235, pypy/branch/dist-newdoc/pypy/doc/contact.txt pypy/extradoc/website/news.txt - copied, changed from r16235, pypy/branch/dist-newdoc/pypy/doc/news.txt Log: move website stuff to new location here (part 1) From hpk at codespeak.net Tue Aug 23 12:58:32 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 12:58:32 +0200 (CEST) Subject: [pypy-svn] r16255 - pypy/branch/dist-newdoc/pypy/doc Message-ID: <20050823105832.EA92B27B39@code1.codespeak.net> Author: hpk Date: Tue Aug 23 12:58:32 2005 New Revision: 16255 Removed: pypy/branch/dist-newdoc/pypy/doc/contact.txt pypy/branch/dist-newdoc/pypy/doc/news.txt Log: remove website stuff from version-dependent doc directory From hpk at codespeak.net Tue Aug 23 13:33:31 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 13:33:31 +0200 (CEST) Subject: [pypy-svn] r16256 - pypy/branch/dist-newdoc/pypy/doc Message-ID: <20050823113331.2344227B3F@code1.codespeak.net> Author: hpk Date: Tue Aug 23 13:33:31 2005 New Revision: 16256 Added: pypy/branch/dist-newdoc/pypy/doc/contact.txt - copied unchanged from r16254, pypy/extradoc/website/contact.txt pypy/branch/dist-newdoc/pypy/doc/news.txt - copied unchanged from r16254, pypy/extradoc/website/news.txt Log: move back the website the main pypy page is going to redirect to the dist simply (avoids URL-referencing messes) From hpk at codespeak.net Tue Aug 23 13:34:00 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 13:34:00 +0200 (CEST) Subject: [pypy-svn] r16257 - pypy/extradoc/website Message-ID: <20050823113400.1C28727B3D@code1.codespeak.net> Author: hpk Date: Tue Aug 23 13:33:58 2005 New Revision: 16257 Removed: pypy/extradoc/website/ Log: remove website from extradoc, it was not such a great idea after all From lac at codespeak.net Tue Aug 23 13:34:51 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Tue, 23 Aug 2005 13:34:51 +0200 (CEST) Subject: [pypy-svn] r16258 - in pypy/dist/pypy/tool: . test Message-ID: <20050823113451.6D31027B3F@code1.codespeak.net> Author: lac Date: Tue Aug 23 13:34:49 2005 New Revision: 16258 Modified: pypy/dist/pypy/tool/getdocstrings.py pypy/dist/pypy/tool/test/test_getdocstrings.py Log: Works now, needs tidying. Modified: pypy/dist/pypy/tool/getdocstrings.py ============================================================================== --- pypy/dist/pypy/tool/getdocstrings.py (original) +++ pypy/dist/pypy/tool/getdocstrings.py Tue Aug 23 13:34:49 2005 @@ -3,12 +3,10 @@ from os import listdir where = autopath.pypydir + '/objspace/std/' -triplequotes = '(' + "'''" + '|' + '"""' + ')' quote = '(' + "'" + '|' + '"' + ')' -doc = re.compile(r"__doc__\s+=\s+" + triplequotes + - r"(?P.*)"+ triplequotes , - re.DOTALL - ) +triplequotes = '(' + "'''" + '|' + '"""' + ')' +# Note: this will produce erroneous result if you nest triple quotes +# in your docstring. def mk_std_filelist(): ''' go to pypy/objs/std and get all the *type.py files ''' @@ -19,9 +17,6 @@ filelist.append(f) return filelist -def mk_typelist(filelist): - ''' generate a list of the types we expect to find in our files''' - return [f[:-7] for f in filelist] def compile_doc(): return re.compile(r"__doc__\s+=\s+" + triplequotes + @@ -30,90 +25,87 @@ ) def compile_typedef(match): - return re.compile(r"(?P\s*)" + return re.compile(r"(?P\s+)" + r"(?P" + match + "_typedef = StdTypeDef+\s*\(\s*" - + quote + match + quote + ",)", - re.DOTALL - ) + + quote + match + quote + ",).*" + + r"(?P^\s+)" + + r"(?P__new__\s*=\s*newmethod)", + re.DOTALL | re.MULTILINE) -def compile_typedef_match(matchstring, sourcefile): - return re.compile(r"(?P\s+)" - + r"(?P" + matchstring - + "_typedef = StdTypeDef+\s*\(\s*" - + quote + matchstring + quote + ",)" - + r"(?P.*\s+)" - + r"(?P__new__)", - re.DOTALL - ).match(sourcefile).span() +def get_pypydoc(match, sourcefile): + doc = compile_doc() + + try: # if this works we already have a docstring + pypydoc = doc.search(sourcefile).group('docstring') + + except AttributeError: # No pypy docstring + return None + + return pypydoc + +def sub_pypydoc(match, sourcefile, cpydoc): + try: + typedef = compile_typedef(match) + tdsearch = typedef.search(sourcefile).group('typeassign') + newsearch = typedef.search(sourcefile).group('newassign') + if not tdsearch: + print 'tdsearch, not found', match + if not newsearch: + print 'newsearch, not found', match + except AttributeError: + pass # so stringtype does not blow up. + return None + +def get_cpydoc(match): + try: + cpydoc = eval(match + '.__doc__') + + except NameError: # No CPython docstring + cpydoc = None + return cpydoc if __name__ == '__main__': - filenames = listdir(where) + #filenames = mk_std_filelist() + #filenames = ['basestringtype.py'] + filenames = ['tupletype.py'] docstrings = [] for f in filenames: - if f.endswith('type.py'): - match = f[:-7] - s = match + '.__doc__' - - try: - cpydoc = eval(match + '.__doc__') - #cpydoc = 'cpy_stuff' - except NameError: # No CPython docstring - cpydoc = None - - sourcefile = file(where + f).read() + match = f[:-7] + sourcefile = file(where + f).read() + + pypydoc = get_pypydoc(match, sourcefile) + cpydoc = get_cpydoc(match) + + if pypydoc: + print match, 'already has a pypydoc' + elif not cpydoc: + print match, 'does not have a cpydoc' + else: + print match, 'has cpydoc. Trying to insert' + docstring="__doc__ = '''" + cpydoc + "'''" - # will produce erroneous result if you nest triple quotes - # in your docstring. + typedef = compile_typedef(match) - doc = re.compile(r"__doc__\s+=\s+" + triplequotes + - r"(?P.*)"+ triplequotes , - re.DOTALL - ) - typedef = re.compile(r"(?P\s+)" - + r"(?P" + match - + "_typedef = StdTypeDef+\s*\(\s*" - + quote + match + quote + ",)" - + r"(?P.*\s+)" - + r"(?P__new__)", - re.DOTALL) - try: - pypydoc = doc.search(sourcefile).group('docstring') - #pypydoc = 'pypy_stuff' - except AttributeError: # No pypy docstring - pypydoc = None - tdsearch = None - try: - tdsearch = typedef.search(sourcefile).group('typeassign') - newsearch = typedef.search(sourcefile).group('newassign') - if tdsearch: - print tdsearch, ' found', match - print newsearch - else: - print tdsearch, ' not found', match - - except AttributeError: - pass # so stringtype does not blow up. - - docstrings.append((match, cpydoc, pypydoc)) - - for (m, c, p) in docstrings: - if p: - print m, 'already has a pypydoc' - elif not c: - print m, 'does not have a cpydoc' - elif not tdsearch: - print m, 'has cpydoc but no ..._typedef = StdTypeDef. Skipping' - else: - print m, 'has cpydoc and ..._typedef = StdTypeDef. Inserting' - - + newsearch = typedef.search(sourcefile) + if newsearch: + print match, '__new__ found' + print newsearch.groupdict() + print newsearch.group('newassign') + print re.sub(newsearch.group('indent') + + newsearch.group('newassign'), + newsearch.group('indent') + + docstring + '\n' + + newsearch.group('indent') + + newsearch.group('newassign'), + sourcefile) + + except AttributeError: + print match, 'no __new__ found' + - - - Modified: pypy/dist/pypy/tool/test/test_getdocstrings.py ============================================================================== --- pypy/dist/pypy/tool/test/test_getdocstrings.py (original) +++ pypy/dist/pypy/tool/test/test_getdocstrings.py Tue Aug 23 13:34:49 2005 @@ -6,8 +6,8 @@ pypy_dir = autopath.pypydir # Naming weirdness: why not both pypy_dir and this_dir or pypydir and thisdir -from pypy.tool.getdocstrings import quote, triplequotes, doc -from pypy.tool.getdocstrings import mk_std_filelist, mk_typelist +from pypy.tool.getdocstrings import quote, triplequotes +from pypy.tool.getdocstrings import mk_std_filelist class TestDocStringInserter: def setup_method(self, method): @@ -25,13 +25,6 @@ 'booltype.py', 'objecttype.py', 'stringtype.py', 'listtype.py'] - def test_typelist(self): - assert mk_typelist(mk_std_filelist()) == [ - 'basestring', 'unicode', 'int', 'none', 'long', - 'slice', 'iter', 'float', 'type', 'dict', - 'dictproxy', 'tuple', 'bool', 'object', 'string', - 'list'] - def test_gottestfile(self): s = self.fd1.read() # whole file as string From arigo at codespeak.net Tue Aug 23 13:43:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 13:43:14 +0200 (CEST) Subject: [pypy-svn] r16259 - pypy/dist/pypy/interpreter Message-ID: <20050823114314.1978427B3F@code1.codespeak.net> Author: arigo Date: Tue Aug 23 13:43:13 2005 New Revision: 16259 Modified: pypy/dist/pypy/interpreter/executioncontext.py Log: (rxe, arigo) comments. Modified: pypy/dist/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/dist/pypy/interpreter/executioncontext.py (original) +++ pypy/dist/pypy/interpreter/executioncontext.py Tue Aug 23 13:43:13 2005 @@ -57,7 +57,13 @@ def bytecode_trace(self, frame): "Trace function called before each bytecode." + + # First, call yield_thread() before each bytecode --- + # XXX this should be called only every N bytecodes, + # as selected by sys.setcheckinterval() self.space.threadlocals.yield_thread() + + # Tracing logic if self.is_tracing or frame.w_f_trace is None: return code = getattr(frame, 'pycode') From arigo at codespeak.net Tue Aug 23 13:49:56 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 13:49:56 +0200 (CEST) Subject: [pypy-svn] r16260 - in pypy/dist/pypy: annotation module/thread/rpython rpython translator/c translator/c/src translator/c/test Message-ID: <20050823114956.E7E6227B3F@code1.codespeak.net> Author: arigo Date: Tue Aug 23 13:49:53 2005 New Revision: 16260 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/module/thread/rpython/exttable.py pypy/dist/pypy/module/thread/rpython/ll_thread.py pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_thread.h pypy/dist/pypy/translator/c/src/thread_nt.h pypy/dist/pypy/translator/c/src/thread_pthread.h pypy/dist/pypy/translator/c/test/test_extfunc.py pypy/dist/pypy/translator/c/test/test_genc.py Log: (rxe, arigo) Finished basic thread support in the C back-end. * lots of hacks to support in the annotator/rtyper the notion of a call-back function, i.e. a function passed as argument to a built-in and that is implicitely called by the built-in. See emulate_pbc_call(). * the thread_*.h have PyThreadStartThread() and PyThreadGetIdent(), called by ll_thread.h. (Still copied from CPython, still untested on NT.) * new test in genc. Also supports view=True in test_genc.compile(). * a fix(?) in bookkeeper.py. Must run all the tests to be sure. Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Tue Aug 23 13:49:53 2005 @@ -192,6 +192,7 @@ self.pbc_callables = None self.pbc_call_sites = {} + self.emulated_pbc_calls = {} self.needs_hash_support = {} @@ -228,6 +229,11 @@ self.consider_pbc_call(pbc, shape, spaceop) self.pbc_call_sites = {} + for fn, shape in self.emulated_pbc_calls.iteritems(): + pbc = SomePBC({fn: True}) + self.consider_pbc_call(pbc, shape) + self.emulated_pbc_calls = {} + for cls in self.needs_hash_support.keys(): for cls2 in self.needs_hash_support: if issubclass(cls, cls2) and cls is not cls2: @@ -475,8 +481,9 @@ else: implicit_init = None - pbc, dontcaresc = self.query_spaceop_callable(spaceop, - implicit_init=implicit_init) + if not (spaceop is implicit_init is None): + pbc, dontcaresc = self.query_spaceop_callable(spaceop, + implicit_init=implicit_init) nonnullcallables = [] for func, classdef in pbc.prebuiltinstances.items(): @@ -521,7 +528,9 @@ self.pbc_call_sites[self.position_key] = shape results = [] - nonnullcallables = [(func, classdef) for func, classdef in pbc.prebuiltinstances.items()] + nonnullcallables = [(func, classdef) + for func, classdef in pbc.prebuiltinstances.items() + if func is not None] mono = len(nonnullcallables) == 1 for func, classdef in nonnullcallables: @@ -534,6 +543,18 @@ return unionof(*results) + def emulate_pbc_call(self, pbc, args_s): + args = self.build_args("simple_call", args_s) + shape = args.rawshape() + for func, classdef in pbc.prebuiltinstances.items(): + if func is not None: + assert not isclassdef(classdef) + if func in self.emulated_pbc_calls: + assert shape == self.emulated_pbc_calls[func] + else: + self.emulated_pbc_calls[func] = shape + return self.pbc_call(pbc, args, True) + # decide_callable(position, func, args, mono) -> callb, key # query_spaceop_callable(spaceop) -> pbc, isspecialcase # get_s_init(decided_cls) -> classdef, s_undecided_init Modified: pypy/dist/pypy/module/thread/rpython/exttable.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/exttable.py (original) +++ pypy/dist/pypy/module/thread/rpython/exttable.py Tue Aug 23 13:49:53 2005 @@ -19,9 +19,24 @@ # ____________________________________________________________ # Built-in functions needed in the rtyper -declare(thread.start_new_thread, int, '%s/start_new_thread' % module) +def ann_startthr(s_bootstrap_function, s_argument_tuple): + from pypy.annotation import model as annmodel + from pypy.annotation.bookkeeper import getbookkeeper + bookkeeper = getbookkeeper() + assert (isinstance(s_argument_tuple, annmodel.SomeTuple) and + len(s_argument_tuple.items) == 1), ( + """thread.start_new_thread(f, arg) is only supported with a tuple of + length 1 for arg""") + s_arg, = s_argument_tuple.items + # XXX hack hack hack: emulate a call to s_bootstrap_function + s_result = bookkeeper.emulate_pbc_call(s_bootstrap_function, [s_arg]) + assert bookkeeper.getpbc(None).contains(s_result), ( + """thread.start_new_thread(f, arg): f() should return None""") + return annmodel.SomeInteger() + +declare(thread.start_new_thread, ann_startthr, '%s/start_new_thread' % module) declare(thread.get_ident, int, '%s/get_ident' % module) -declare(thread.allocate_lock, thread.LockType, '%s/allocate_lock' % module) +declare(thread.allocate_lock, thread.LockType,'%s/allocate_lock' % module) # ____________________________________________________________ # thread.error can be raised by the above Modified: pypy/dist/pypy/module/thread/rpython/ll_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/rpython/ll_thread.py (original) +++ pypy/dist/pypy/module/thread/rpython/ll_thread.py Tue Aug 23 13:49:53 2005 @@ -18,7 +18,14 @@ return ll_thread_start(funcptr, argument) def ll_thread_start(funcptr, argument): - return thread.start_new_thread(funcptr, (argument,)) + #return thread.start_new_thread(funcptr, (argument,)) + # XXX we just return an integer here, because we cannot really call back + # XXX into thread.start_new_thread(). Indeed, 'funcptr' is not a normal + # XXX function object, but a low-level pointer to a _func. This also + # XXX confuses the annotator. + # note that running this won't really work, but anyway llinterpreter + # is probably quite confused if we start multiple threads + return 1234 ll_thread_start.suggested_primitive = True def ll_thread_get_ident(): Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Tue Aug 23 13:49:53 2005 @@ -702,15 +702,25 @@ def gendirectcall(self, ll_function, *args_v): rtyper = self.rtyper args_s = [] + newargs_v = [] for v in args_v: if v.concretetype == Void: s_value = rtyper.binding(v) if not s_value.is_constant(): raise TyperError("non-constant variable of type Void") + if not isinstance(s_value, annmodel.SomePBC): + # a Void non-PBC constant: can be a SomePtr pointing to a + # constant function. + assert isinstance(s_value, annmodel.SomePtr) + # Drop the 'const'. + s_value = annmodel.SomePtr(s_value.ll_ptrtype) + # Modify args_v so that 'v' gets the llptr concretetype + # stored in s_value + v = inputconst(s_value.ll_ptrtype, v.value) args_s.append(s_value) - assert isinstance(s_value, annmodel.SomePBC) else: args_s.append(annmodel.lltype_to_annotation(v.concretetype)) + newargs_v.append(v) self.rtyper.call_all_setups() # compute ForwardReferences now dontcare, spec_function = annotate_lowlevel_helper(rtyper.annotator, ll_function, args_s) @@ -718,7 +728,7 @@ # build the 'direct_call' operation f = self.rtyper.getfunctionptr(spec_function) c = inputconst(typeOf(f), f) - return self.genop('direct_call', [c]+list(args_v), + return self.genop('direct_call', [c]+newargs_v, resulttype = typeOf(f).TO.RESULT) def genexternalcall(self, fnname, args_v, resulttype=None, **flags): Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Aug 23 13:49:53 2005 @@ -37,9 +37,11 @@ 'LL_strtod_parts_to_float', ll_strtod.ll_strtod_formatd: 'LL_strtod_formatd', - ll_thread.ll_newlock: 'LL_thread_newlock', - ll_thread.ll_acquirelock: 'LL_thread_acquirelock', - ll_thread.ll_releaselock: 'LL_thread_releaselock', + ll_thread.ll_newlock: 'LL_thread_newlock', + ll_thread.ll_acquirelock: 'LL_thread_acquirelock', + ll_thread.ll_releaselock: 'LL_thread_releaselock', + ll_thread.ll_thread_start: 'LL_thread_start', + ll_thread.ll_thread_get_ident: 'LL_thread_get_ident', } #______________________________________________________ Modified: pypy/dist/pypy/translator/c/src/ll_thread.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_thread.h (original) +++ pypy/dist/pypy/translator/c/src/ll_thread.h Tue Aug 23 13:49:53 2005 @@ -35,3 +35,18 @@ RPyThreadReleaseLock(lock); } } + +long LL_thread_start(void (*func)(void *), void *arg) +{ + /* XXX func() should not raise exceptions */ + long ident = RPyThreadStart(func, arg); + if (ident == -1) + RPyRaiseSimpleException(PyExc_thread_error, + "can't start new thread"); + return ident; +} + +long LL_thread_get_ident(void) +{ + return RPyThreadGetIdent(); +} Modified: pypy/dist/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/dist/pypy/translator/c/src/thread_nt.h (original) +++ pypy/dist/pypy/translator/c/src/thread_nt.h Tue Aug 23 13:49:53 2005 @@ -8,6 +8,68 @@ #include #include + +/* + * Thread support. + */ + +/* + * Return the thread Id instead of an handle. The Id is said to uniquely + identify the thread in the system + */ +#define PyThreadGetIdent GetCurrentThreadId + +typedef struct { + void (*func)(void*); + void *arg; + long id; + HANDLE done; +} callobj; + +static int +bootstrap(void *call) +{ + callobj *obj = (callobj*)call; + /* copy callobj since other thread might free it before we're done */ + void (*func)(void*) = obj->func; + void *arg = obj->arg; + + obj->id = PyThreadGetIdent(); + ReleaseSemaphore(obj->done, 1, NULL); + func(arg); + return 0; +} + +long PyThreadStart(void (*func)(void *), void *arg) +{ + unsigned long rv; + callobj obj; + + obj.id = -1; /* guilty until proved innocent */ + obj.func = func; + obj.arg = arg; + obj.done = CreateSemaphore(NULL, 0, 1, NULL); + if (obj.done == NULL) + return -1; + + rv = _beginthread(bootstrap, 0, &obj); /* use default stack size */ + if (rv == (unsigned long)-1) { + /* I've seen errno == EAGAIN here, which means "there are + * too many threads". + */ + obj.id = -1; + } + else { + /* wait for thread to initialize, so we can get its id */ + WaitForSingleObject(obj.done, INFINITE); + assert(obj.id != -1); + } + CloseHandle((HANDLE)obj.done); + return obj.id; +} + +/************************************************************/ + typedef struct RPyOpaque_ThreadLock { LONG owned ; DWORD thread_id ; Modified: pypy/dist/pypy/translator/c/src/thread_pthread.h ============================================================================== --- pypy/dist/pypy/translator/c/src/thread_pthread.h (original) +++ pypy/dist/pypy/translator/c/src/thread_pthread.h Tue Aug 23 13:49:53 2005 @@ -40,6 +40,69 @@ #define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; } +/* XXX This implementation is considered (to quote Tim Peters) "inherently + hosed" because: + - It does not guarantee the promise that a non-zero integer is returned. + - The cast to long is inherently unsafe. + - It is not clear that the 'volatile' (for AIX?) and ugly casting in the + latter return statement (for Alpha OSF/1) are any longer necessary. +*/ +long RPyThreadGetIdent(void) +{ + 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 +} + +long RPyThreadStart(void (*func)(void *), void *arg) +{ + pthread_t th; + int status; +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + pthread_attr_t attrs; +#endif + +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + pthread_attr_init(&attrs); +#endif +#ifdef THREAD_STACK_SIZE + pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE); +#endif +#if defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) && !defined(__FreeBSD__) + pthread_attr_setscope(&attrs, PTHREAD_SCOPE_SYSTEM); +#endif + + status = pthread_create(&th, +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + &attrs, +#else + (pthread_attr_t*)NULL, +#endif + (void* (*)(void *))func, + (void *)arg + ); + +#if defined(THREAD_STACK_SIZE) || defined(PTHREAD_SYSTEM_SCHED_SUPPORTED) + pthread_attr_destroy(&attrs); +#endif + if (status != 0) + return -1; + + pthread_detach(th); + +#if SIZEOF_PTHREAD_T <= SIZEOF_LONG + return (long) th; +#else + return (long) *(long *) &th; +#endif +} + + /************************************************************/ #ifdef USE_SEMAPHORES /************************************************************/ Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Tue Aug 23 13:49:53 2005 @@ -321,3 +321,54 @@ f = compile(fn, []) res = f() assert res is True + +def test_simple_start_new_thread(): + import thread + import pypy.module.thread.rpython.exttable # for declare()/declaretype() + class Arg: + pass + def mythreadedfunction(arg): + assert arg.value == 42 + def myotherthreadedfunction(arg): + assert arg.value == 43 + def fn(i): + a42 = Arg() + a42.value = 42 + a43 = Arg() + a43.value = 43 + thread.start_new_thread(mythreadedfunction, (a42,)) + thread.start_new_thread(myotherthreadedfunction, (a43,)) + if i == 1: + x = mythreadedfunction + a = a42 + else: + x = myotherthreadedfunction + a = a43 + thread.start_new_thread(x, (a,)) + return 42 + f = compile(fn, [int]) + res = f(1) + assert res == 42 + +def test_start_new_thread(): + import thread + import pypy.module.thread.rpython.exttable # for declare()/declaretype() + class Arg: + pass + def mythreadedfunction(arg): + arg.x += 37 + arg.myident = thread.get_ident() + arg.lock.release() + def fn(): + a = Arg() + a.x = 5 + a.lock = thread.allocate_lock() + a.lock.acquire(True) + ident = thread.start_new_thread(mythreadedfunction, (a,)) + assert ident != thread.get_ident() + a.lock.acquire(True) # wait for the thread to finish + assert a.myident == ident + return a.x + f = compile(fn, []) + res = f() + assert res == 42 Modified: pypy/dist/pypy/translator/c/test/test_genc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_genc.py (original) +++ pypy/dist/pypy/translator/c/test/test_genc.py Tue Aug 23 13:49:53 2005 @@ -26,10 +26,12 @@ include_dirs = [os.path.dirname(autopath.this_dir)]) return m -def compile(fn, argtypes): +def compile(fn, argtypes, view=False): t = Translator(fn) t.annotate(argtypes) t.specialize() + if view: + t.view() t.backend_optimizations() db = LowLevelDatabase(t) entrypoint = db.get(pyobjectptr(fn)) @@ -209,3 +211,16 @@ f1 = compile(fn, []) res = f1() assert res > 0 and res == res / 2 + + +def test_x(): + class A: + pass + a = A() + a.d = {} + a.d['hey'] = 42 + def t(): + a.d['hey'] = 2 + return a.d['hey'] + f = compile(t, []) + assert f() == 2 From hpk at codespeak.net Tue Aug 23 13:55:49 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 13:55:49 +0200 (CEST) Subject: [pypy-svn] r16261 - pypy/dist/pypy/translator/goal Message-ID: <20050823115549.DF4ED27B3F@code1.codespeak.net> Author: hpk Date: Tue Aug 23 13:55:47 2005 New Revision: 16261 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: get rid of deprecated checker() API Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Tue Aug 23 13:55:47 2005 @@ -261,7 +261,7 @@ from py import path try: if stabledir.check(dir=1): - for x in udir.visit(path.checker(file=1)): + for x in udir.visit(lambda x: x.check(file=1)): target = stabledir.join(x.relto(udir)) if target.check(): target.remove() From pedronis at codespeak.net Tue Aug 23 14:02:24 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 23 Aug 2005 14:02:24 +0200 (CEST) Subject: [pypy-svn] r16262 - pypy/dist/pypy/translator/c Message-ID: <20050823120224.DC83A27B3F@code1.codespeak.net> Author: pedronis Date: Tue Aug 23 14:02:22 2005 New Revision: 16262 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/node.py Log: reorganized code in node.py in preparation to move the refcounting logic to the respective policy through hooks (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Aug 23 14:02:22 2005 @@ -74,7 +74,7 @@ argtypes = ', '.join(argtypes) or 'void' return resulttype.replace('@', '(@)(%s)' % argtypes) elif isinstance(T, OpaqueType): - if T == RuntimeTypeInfo: + if T == RuntimeTypeInfo: # xxx -> gc return 'void (@)(void *)' # void dealloc_xx(struct xx *) elif hasattr(T, '_exttypeinfo'): # for external types (pypy.rpython.extfunctable.declaretype()) @@ -128,8 +128,8 @@ return 'Py_XINCREF(%s);' % expr else: defnode = self.gettypedefnode(T.TO) - if defnode.refcount is not None: - return 'if (%s) %s->%s++;' % (expr, expr, defnode.refcount) + if defnode.gcheader is not None: + return 'if (%s) %s->%s++;' % (expr, expr, defnode.gcheader) return '' def cdecrefstmt(self, expr, T): @@ -138,10 +138,13 @@ return 'Py_XDECREF(%s);' % expr else: defnode = self.gettypedefnode(T.TO) - if defnode.refcount is not None: + if defnode.gcheader is not None: + dealloc = 'OP_FREE' + if defnode.gcinfo: + dealloc = defnode.gcinfo.deallocator or dealloc return 'if (%s && !--%s->%s) %s(%s);' % (expr, expr, - defnode.refcount, - defnode.deallocator or 'OP_FREE', + defnode.gcheader, + dealloc, expr) return '' Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Tue Aug 23 14:02:22 2005 @@ -397,8 +397,7 @@ T = self.lltypemap(op.result) newvalue = self.expr(op.result, special_case_void=False) result = ['%s = %s;' % (newvalue, sourceexpr)] - # need to adjust the refcount of the result - + # need to adjust the refcount of the result only for PyObjects line = self.pyobj_incref_expr(newvalue, T) if line: result.append(line) @@ -480,7 +479,7 @@ eresult, err), '%s->%s = 0;' % (eresult, # xxx the incref is generically done on the results - self.db.gettypedefnode(TYPE).refcount), + self.db.gettypedefnode(TYPE).gcheader), ] return '\t'.join(result) @@ -509,7 +508,7 @@ '%s->%s = %s;' % (eresult, lenfld, elength), '%s->%s = 0;' % (eresult, # xxx the incref is generically done on the results - nodedef.refcount), + nodedef.gcheader), ] return '\t'.join(result) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Aug 23 14:02:22 2005 @@ -39,15 +39,18 @@ def push_alive_nopyobj(self, expr, T): defnode = self.db.gettypedefnode(T.TO) - if defnode.refcount is not None: - return 'if (%s) %s->%s++;' % (expr, expr, defnode.refcount) + if defnode.gcheader is not None: + return 'if (%s) %s->%s++;' % (expr, expr, defnode.gcheader) def pop_alive_nopyobj(self, expr, T): defnode = self.db.gettypedefnode(T.TO) - if defnode.refcount is not None: + if defnode.gcheader is not None: + dealloc = 'OP_FREE' + if defnode.gcinfo: + dealloc = defnode.gcinfo.deallocator or dealloc return 'if (%s && !--%s->%s) %s(%s);' % (expr, expr, - defnode.refcount, - defnode.deallocator or 'OP_FREE', + defnode.gcheader, + dealloc, expr) def push_alive_op_result(self, opname, expr, T): Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Aug 23 14:02:22 2005 @@ -12,20 +12,27 @@ from pypy.rpython.rstr import STR -def needs_refcount(T): +def needs_gcheader(T): if not isinstance(T, GC_CONTAINER): return False if isinstance(T, GcStruct): if T._names and isinstance(T._flds[T._names[0]], GC_CONTAINER): - return False # refcount already in the first field + return False # gcheader already in the first field return True - -class StructDefNode: - refcount = None +class GcInfo: deallocator = None static_deallocator = None + +class StructDefNode: + gcheader = None + + gcinfo = None + + #deallocator = None + #static_deallocator = None + def __init__(self, db, STRUCT, varlength=1): self.db = db self.STRUCT = STRUCT @@ -44,18 +51,19 @@ self.dependencies = {} self.prefix = somelettersfrom(STRUCT._name) + '_' - # look up the reference counter field - if needs_refcount(STRUCT): - self.refcount = 'refcount' + # look up the gcheader field + if needs_gcheader(STRUCT): + self.gcheader = 'refcount' elif isinstance(STRUCT, GcStruct): - # refcount in the first field + # gcheader in the first field T = self.c_struct_field_type(STRUCT._names[0]) assert isinstance(T, GC_CONTAINER) firstdefnode = db.gettypedefnode(T) firstfieldname = self.c_struct_field_name(STRUCT._names[0]) - self.refcount = '%s.%s' % (firstfieldname, firstdefnode.refcount) + self.gcheader = '%s.%s' % (firstfieldname, firstdefnode.gcheader) # check here that there is enough run-time type information to # handle this case + # xxx -> gc hook getRuntimeTypeInfo(STRUCT) getRuntimeTypeInfo(T) @@ -74,34 +82,38 @@ typename = db.gettype(T, who_asks=self) self.fields.append((self.c_struct_field_name(name), typename)) + rtti = None + if isinstance(STRUCT, GcStruct): + try: + rtti = getRuntimeTypeInfo(STRUCT) + except ValueError: + pass + # do we need deallocator(s)? - if self.refcount and varlength == 1: - self.deallocator = db.namespace.uniquename('dealloc_'+self.barename) + if varlength == 1: + if self.gcheader: # xxx -> gc + gcinfo = self.gcinfo = GcInfo() - # are two deallocators needed (a dynamic one for DECREF, which checks - # the real type of the structure and calls the static deallocator) ? - rtti = None - if isinstance(STRUCT, GcStruct): - try: - rtti = getRuntimeTypeInfo(STRUCT) - except ValueError: - pass - if rtti is not None: - self.static_deallocator = db.namespace.uniquename( - 'staticdealloc_'+self.barename) - fnptr = rtti._obj.query_funcptr - if fnptr is None: - raise NotImplementedError( - "attachRuntimeTypeInfo(): please provide a function") - self.rtti_query_funcptr = db.get(fnptr) - T = typeOf(fnptr).TO.ARGS[0] - self.rtti_query_funcptr_argtype = db.gettype(T) - else: - # is a deallocator really needed, or would it be empty? - if list(self.deallocator_lines('')): - self.static_deallocator = self.deallocator + gcinfo.deallocator = db.namespace.uniquename('dealloc_'+self.barename) + + # are two deallocators needed (a dynamic one for DECREF, which checks + # the real type of the structure and calls the static deallocator) ? + if rtti is not None: + gcinfo.static_deallocator = db.namespace.uniquename( + 'staticdealloc_'+self.barename) + fnptr = rtti._obj.query_funcptr + if fnptr is None: + raise NotImplementedError( + "attachRuntimeTypeInfo(): please provide a function") + gcinfo.rtti_query_funcptr = db.get(fnptr) + T = typeOf(fnptr).TO.ARGS[0] + gcinfo.rtti_query_funcptr_argtype = db.gettype(T) else: - self.deallocator = None + # is a deallocator really needed, or would it be empty? + if list(self.deallocator_lines('')): + gcinfo.static_deallocator = gcinfo.deallocator + else: + gcinfo.deallocator = None def c_struct_field_name(self, name): return self.prefix + name @@ -116,7 +128,7 @@ def definition(self, phase): if phase == 1: yield 'struct %s {' % self.name - if needs_refcount(self.STRUCT): + if needs_gcheader(self.STRUCT): # xxx -> gc yield '\tlong refcount;' for name, typename in self.fields: line = '%s;' % cdecl(typename, name) @@ -124,31 +136,35 @@ line = '/* %s */' % line yield '\t' + line yield '};' - if self.deallocator: - yield 'void %s(struct %s *);' % (self.deallocator, self.name) - - elif phase == 2: - if self.static_deallocator: - yield 'void %s(struct %s *p) {' % (self.static_deallocator, + if self.gcinfo: # xxx -> gc + gcinfo = self.gcinfo + if gcinfo.deallocator: + yield 'void %s(struct %s *);' % (gcinfo.deallocator, self.name) + + elif phase == 2: # xxx -> gc + if self.gcinfo: + gcinfo = self.gcinfo + if gcinfo.static_deallocator: + yield 'void %s(struct %s *p) {' % (gcinfo.static_deallocator, self.name) - for line in self.deallocator_lines('(*p)'): - yield '\t' + line - yield '\tOP_FREE(p);' - yield '}' - if self.deallocator and self.deallocator != self.static_deallocator: - yield 'void %s(struct %s *p) {' % (self.deallocator, self.name) - yield '\tvoid (*staticdealloc) (void *);' - # the refcount should be 0; temporarily bump it to 1 - yield '\tp->%s = 1;' % (self.refcount,) - # cast 'p' to the type expected by the rtti_query function - yield '\tstaticdealloc = %s((%s) p);' % ( - self.rtti_query_funcptr, - cdecl(self.rtti_query_funcptr_argtype, '')) - yield '\tif (!--p->%s)' % (self.refcount,) - yield '\t\tstaticdealloc(p);' - yield '}' + for line in self.deallocator_lines('(*p)'): + yield '\t' + line + yield '\tOP_FREE(p);' + yield '}' + if gcinfo.deallocator and gcinfo.deallocator != gcinfo.static_deallocator: + yield 'void %s(struct %s *p) {' % (gcinfo.deallocator, self.name) + yield '\tvoid (*staticdealloc) (void *);' + # the refcount should be 0; temporarily bump it to 1 + yield '\tp->%s = 1;' % (self.gcheader,) + # cast 'p' to the type expected by the rtti_query function + yield '\tstaticdealloc = %s((%s) p);' % ( + gcinfo.rtti_query_funcptr, + cdecl(gcinfo.rtti_query_funcptr_argtype, '')) + yield '\tif (!--p->%s)' % (self.gcheader,) + yield '\t\tstaticdealloc(p);' + yield '}' - def deallocator_lines(self, prefix): + def deallocator_lines(self, prefix): # xxx xxx rename, re-factor generic_dealloc use STRUCT = self.STRUCT for name in STRUCT._names: FIELD_T = self.c_struct_field_type(name) @@ -171,8 +187,8 @@ class ArrayDefNode: - refcount = None - deallocator = None + gcheader = None + gcinfo = None def __init__(self, db, ARRAY, varlength=1): self.db = db @@ -195,8 +211,8 @@ self.dependencies = {} # look up the reference counter field - if needs_refcount(ARRAY): - self.refcount = 'refcount' + if needs_gcheader(ARRAY): + self.gcheader = 'refcount' # xxx -> gc def setup(self): db = self.db @@ -205,8 +221,10 @@ self.itemtypename = db.gettype(ARRAY.OF, who_asks=self) # is a specific deallocator needed? - if self.refcount and varlength == 1 and list(self.deallocator_lines('')): - self.deallocator = db.namespace.uniquename('dealloc_'+self.barename) + if varlength == 1: + if self.gcheader and list(self.deallocator_lines('')): + gcinfo = self.gcinfo = GcInfo() + gcinfo.deallocator = db.namespace.uniquename('dealloc_'+self.barename) def access_expr(self, baseexpr, index): return '%s.items[%d]' % (baseexpr, index) @@ -214,25 +232,30 @@ def definition(self, phase): if phase == 1: yield 'struct %s {' % self.name - if needs_refcount(self.ARRAY): - yield '\tlong refcount;' + if needs_gcheader(self.ARRAY): + yield '\tlong refcount;' # xxx -> gc yield '\tlong length;' line = '%s;' % cdecl(self.itemtypename, 'items[%d]'% self.varlength) if self.ARRAY.OF == Void: # strange line = '/* %s */' % line yield '\t' + line yield '};' - if self.deallocator: - yield 'void %s(struct %s *a);' % (self.deallocator, self.name) + if self.gcinfo: # xxx -> gc + gcinfo = self.gcinfo + if gcinfo.deallocator: + yield 'void %s(struct %s *a);' % (gcinfo.deallocator, self.name) - elif phase == 2 and self.deallocator: - yield 'void %s(struct %s *a) {' % (self.deallocator, self.name) - for line in self.deallocator_lines('(*a)'): - yield '\t' + line - yield '\tOP_FREE(a);' - yield '}' + elif phase == 2: + if self.gcinfo: # xxx -> gc + gcinfo = self.gcinfo + if gcinfo.deallocator: + yield 'void %s(struct %s *a) {' % (gcinfo.deallocator, self.name) + for line in self.deallocator_lines('(*a)'): + yield '\t' + line + yield '\tOP_FREE(a);' + yield '}' - def deallocator_lines(self, prefix): + def deallocator_lines(self, prefix): # xxx xxx rename, re-factor generic_dealloc use 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' @@ -287,7 +310,7 @@ return [] -def generic_dealloc(db, expr, T): +def generic_dealloc(db, expr, T): # xxx -> gc, refactor PyObjPtr case if isinstance(T, Ptr) and T._needsgc(): line = db.cdecrefstmt(expr, T) if line: @@ -367,7 +390,7 @@ def initializationexpr(self, decoration=''): yield '{' - if needs_refcount(self.T): + if needs_gcheader(self.T): # xxx -> gc yield '\tREFCOUNT_IMMORTAL,' defnode = self.db.gettypedefnode(self.T) for name in self.T._names: @@ -396,7 +419,7 @@ def initializationexpr(self, decoration=''): yield '{' - if needs_refcount(self.T): + if needs_gcheader(self.T): # xxx -> gc yield '\tREFCOUNT_IMMORTAL,' if self.T.OF == Void or len(self.obj.items) == 0: yield '\t%d' % len(self.obj.items) @@ -552,7 +575,7 @@ typename = 'void (@)(void *)' includes = () - def __init__(self, db, T, obj): + def __init__(self, db, T, obj): # xxx this supplies rtti value -> gc assert T == RuntimeTypeInfo assert isinstance(obj.about, GcStruct) self.db = db @@ -561,7 +584,7 @@ defnode = db.gettypedefnode(obj.about) self.implementationtypename = 'void (@)(struct %s *)' % ( defnode.name,) - self.name = defnode.static_deallocator + self.name = defnode.gcinfo.static_deallocator self.ptrname = '((void (*)(void *)) %s)' % (self.name,) def enum_dependencies(self): From hpk at codespeak.net Tue Aug 23 14:20:00 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 14:20:00 +0200 (CEST) Subject: [pypy-svn] r16263 - in pypy/dist/pypy: doc doc/image doc/revreport doc/tool documentation Message-ID: <20050823122000.1C41127B41@code1.codespeak.net> Author: hpk Date: Tue Aug 23 14:19:59 2005 New Revision: 16263 Added: pypy/dist/pypy/doc/ (props changed) - copied from r16262, pypy/branch/dist-newdoc/pypy/doc/ pypy/dist/pypy/doc/__init__.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/__init__.py pypy/dist/pypy/doc/_ref.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/_ref.txt pypy/dist/pypy/doc/architecture.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/architecture.txt pypy/dist/pypy/doc/coding-guide.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/coding-guide.txt pypy/dist/pypy/doc/confrest.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/confrest.py pypy/dist/pypy/doc/conftest.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/conftest.py pypy/dist/pypy/doc/contact.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/contact.txt pypy/dist/pypy/doc/contributor.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/contributor.txt pypy/dist/pypy/doc/ext-functions-draft.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/ext-functions-draft.txt pypy/dist/pypy/doc/extradoc.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/extradoc.txt pypy/dist/pypy/doc/faq.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/faq.txt pypy/dist/pypy/doc/gc_planning.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/gc_planning.txt pypy/dist/pypy/doc/getting-started.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/getting-started.txt pypy/dist/pypy/doc/image/ - copied from r16262, pypy/branch/dist-newdoc/pypy/doc/image/ pypy/dist/pypy/doc/image/translation.sxd - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/image/translation.sxd pypy/dist/pypy/doc/index.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/index.txt pypy/dist/pypy/doc/interpreter.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/interpreter.txt pypy/dist/pypy/doc/misc.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/misc.txt pypy/dist/pypy/doc/navlist - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/navlist pypy/dist/pypy/doc/news.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/news.txt pypy/dist/pypy/doc/newstructure - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/newstructure pypy/dist/pypy/doc/objspace.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/objspace.txt pypy/dist/pypy/doc/parser-design.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/parser-design.txt pypy/dist/pypy/doc/redirections - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/redirections pypy/dist/pypy/doc/release-0.6.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/release-0.6.txt pypy/dist/pypy/doc/revreport/ (props changed) - copied from r16262, pypy/branch/dist-newdoc/pypy/doc/revreport/ pypy/dist/pypy/doc/revreport/__init__.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/revreport/__init__.py pypy/dist/pypy/doc/revreport/autopath.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/revreport/autopath.py pypy/dist/pypy/doc/revreport/delta.css - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/revreport/delta.css pypy/dist/pypy/doc/revreport/delta.js - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/revreport/delta.js pypy/dist/pypy/doc/revreport/delta.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/revreport/delta.py pypy/dist/pypy/doc/revreport/revreport.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/revreport/revreport.py pypy/dist/pypy/doc/style.css - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/style.css pypy/dist/pypy/doc/svn-help.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/svn-help.txt pypy/dist/pypy/doc/test_redirections.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/test_redirections.py pypy/dist/pypy/doc/theory.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/theory.txt pypy/dist/pypy/doc/tool/ (props changed) - copied from r16262, pypy/branch/dist-newdoc/pypy/doc/tool/ pypy/dist/pypy/doc/tool/__init__.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/tool/__init__.py pypy/dist/pypy/doc/tool/makecontributor.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/tool/makecontributor.py pypy/dist/pypy/doc/tool/makeref.py - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/tool/makeref.py pypy/dist/pypy/doc/translation.txt - copied unchanged from r16262, pypy/branch/dist-newdoc/pypy/doc/translation.txt Removed: pypy/dist/pypy/documentation/ Log: merge the documentation branch back to dist From hpk at codespeak.net Tue Aug 23 14:31:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 14:31:06 +0200 (CEST) Subject: [pypy-svn] r16264 - pypy/branch/dist-newdoc Message-ID: <20050823123106.356B827B41@code1.codespeak.net> Author: hpk Date: Tue Aug 23 14:31:05 2005 New Revision: 16264 Removed: pypy/branch/dist-newdoc/ Log: branch is merged and can go From tismer at codespeak.net Tue Aug 23 14:42:10 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 14:42:10 +0200 (CEST) Subject: [pypy-svn] r16265 - pypy/dist/pypy Message-ID: <20050823124210.61D4A27B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 14:42:09 2005 New Revision: 16265 Modified: pypy/dist/pypy/conftest.py Log: typo in exception handler. We need a test that tests conftest if the space doesn't work :-)) Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Tue Aug 23 14:42:09 2005 @@ -66,7 +66,7 @@ if option.verbose: import traceback traceback.print_exc() - py.test.fail("fatal: cannot initialize objspace: %r" %(module.Space,)) + py.test.fail("fatal: cannot initialize objspace: %r" %(Space,)) _spacecache[name] = space space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) From nik at codespeak.net Tue Aug 23 15:13:43 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 15:13:43 +0200 (CEST) Subject: [pypy-svn] r16266 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050823131343.71D0027B41@code1.codespeak.net> Author: nik Date: Tue Aug 23 15:13:42 2005 New Revision: 16266 Modified: pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_interp_sre.py Log: various fixes towards annotatability. removed use of array. Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Tue Aug 23 15:13:42 2005 @@ -1,7 +1,6 @@ from pypy.interpreter.baseobjspace import ObjSpace, Wrappable # XXX is it allowed to import app-level module like this? from pypy.module._sre.app_info import CODESIZE -from pypy.module.array.app_array import array from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.gateway import interp2app @@ -62,7 +61,7 @@ # This id marks the end of a group. self.lastindex = mark_nr / 2 + 1 if mark_nr >= len(self.marks): - self.marks.extend([None] * (mark_nr - len(self.marks) + 1)) + self.marks.extend([-1] * (mark_nr - len(self.marks) + 1)) self.marks[mark_nr] = self.space.int_w(w_position) def get_marks(self, w_group_index): @@ -79,9 +78,7 @@ regs = [self.space.newtuple([self.space.wrap(self.start), self.space.wrap(self.string_position)])] for group in range(self.space.int_w(w_group_count)): mark_index = 2 * group - if mark_index + 1 < len(self.marks) \ - and self.marks[mark_index] is not None \ - and self.marks[mark_index + 1] is not None: + if mark_index + 1 < len(self.marks): regs.append(self.space.newtuple([self.space.wrap(self.marks[mark_index]), self.space.wrap(self.marks[mark_index + 1])])) else: @@ -128,7 +125,6 @@ lower = interp2app(W_State.lower), ) - #### Category helpers ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, @@ -143,9 +139,7 @@ underline = ord("_") # Static list of all unicode codepoints reported by Py_UNICODE_ISLINEBREAK. -# Using a dict as a poor man's set. -uni_linebreaks = {10: True, 13: True, 28: True, 29: True, 30: True, 133: True, - 8232: True, 8233: True} +uni_linebreaks = [10, 13, 28, 29, 30, 133, 8232, 8233] def is_digit(space, w_char): code = space.int_w(space.ord(w_char)) @@ -186,7 +180,7 @@ def is_uni_linebreak(space, w_char): code = space.int_w(space.ord(w_char)) - return uni_linebreaks.has_key(code) + return code in uni_linebreaks #### Category dispatch @@ -217,6 +211,11 @@ class MatchContext: # XXX This is not complete. It's tailored to at dispatch currently. + + # XXX These constants should maybe not be here + OK = 1 + NOT_OK = -1 + NOT_FINISHED = 0 def __init__(self, space, pattern_codes, w_string, string_position, end): self.space = space @@ -225,7 +224,7 @@ self.string_position = string_position self.end = end self.code_position = 0 - self.set_ok = True # XXX maybe get rid of this + self.set_ok = self.OK # XXX maybe get rid of this def peek_char(self, peek=0): return self.space.getitem(self.w_string, @@ -318,17 +317,18 @@ char_code = space.int_w(w_char_code) context = MatchContext(space, pattern_codes, w_string, space.int_w(w_string_position), space.int_w(space.len(w_string))) - result = None - while result is None: + result = MatchContext.NOT_FINISHED + while result == MatchContext.NOT_FINISHED: opcode = context.peek_code() if opcode >= len(set_dispatch_table): return space.newbool(False) function = set_dispatch_table[opcode] result = function(space, context, char_code) - return space.newbool(result) + print result + return space.newbool(result == MatchContext.OK) def set_failure(space, ctx, char_code): - return not ctx.set_ok + return -ctx.set_ok def set_literal(space, ctx, char_code): # @@ -336,6 +336,7 @@ return ctx.set_ok else: ctx.skip_code(2) + return MatchContext.NOT_FINISHED def set_category(space, ctx, char_code): # @@ -344,6 +345,7 @@ return ctx.set_ok else: ctx.skip_code(2) + return MatchContext.NOT_FINISHED def set_charset(space, ctx, char_code): # (16 bits per code word) @@ -358,16 +360,19 @@ & (1 << (char_code & 31)): return ctx.set_ok ctx.skip_code(8) # skip bitmap + return MatchContext.NOT_FINISHED def set_range(space, ctx, char_code): # if ctx.peek_code(1) <= char_code <= ctx.peek_code(2): return ctx.set_ok ctx.skip_code(3) + return MatchContext.NOT_FINISHED def set_negate(space, ctx, char_code): - ctx.set_ok = not ctx.set_ok + ctx.set_ok = -ctx.set_ok ctx.skip_code(1) + return MatchContext.NOT_FINISHED def set_bigcharset(space, ctx, char_code): # <256 blockindices> @@ -377,19 +382,37 @@ if char_code < 65536: block_index = char_code >> 8 # NB: there are CODESIZE block indices per bytecode - # XXX can we really use array here? - a = array("B") - a.fromstring(array(CODESIZE == 2 and "H" or "I", - [ctx.peek_code(block_index / CODESIZE)]).tostring()) + a = to_byte_array(ctx.peek_code(block_index / CODESIZE)) block = a[block_index % CODESIZE] ctx.skip_code(256 / CODESIZE) # skip block indices + if CODESIZE == 2: + shift = 4 + else: + shift = 5 block_value = ctx.peek_code(block * (32 / CODESIZE) - + ((char_code & 255) >> (CODESIZE == 2 and 4 or 5))) + + ((char_code & 255) >> shift)) if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): return ctx.set_ok else: ctx.skip_code(256 / CODESIZE) # skip block indices ctx.skip_code(count * (32 / CODESIZE)) # skip blocks + return MatchContext.NOT_FINISHED + +def to_byte_array(int_value): + """Creates a list of bytes out of an integer representing data that is + CODESIZE bytes wide.""" + import sys + byte_array = [0] * CODESIZE + for i in range(CODESIZE): + byte_array[i] = int_value & 0xff + int_value = int_value >> 8 + if sys.byteorder == "big": + # Uhm, maybe there's a better way to reverse lists + byte_array_reversed = [0] * CODESIZE + for i in range(CODESIZE): + byte_array_reversed[-i-1] = byte_array[i] + byte_array = byte_array_reversed + return byte_array set_dispatch_table = [ set_failure, None, None, None, None, None, None, None, None, Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Tue Aug 23 15:13:42 2005 @@ -1,5 +1,6 @@ """Interp-level _sre tests.""" import autopath +import sys from py.test import raises import pypy.module._sre.interp_sre as isre @@ -80,3 +81,23 @@ def test_getlower(space): assert space.int_w(isre.getlower(space, space.wrap(ord("A")), space.wrap(0))) == ord("a") + +def test_get_byte_array(space): + if sys.byteorder == "big": + if isre.CODESIZE == 2: + assert [0, 1] == isre.to_byte_array(1) + assert [1, 0] == isre.to_byte_array(256) + assert [1, 2] == isre.to_byte_array(258) + else: + assert [0, 0, 0, 1] == isre.to_byte_array(1) + assert [0, 0, 1, 0] == isre.to_byte_array(256) + assert [1, 2, 3, 4] == isre.to_byte_array(0x01020304) + else: + if isre.CODESIZE == 2: + assert [1, 0] == isre.to_byte_array(1) + assert [0, 1] == isre.to_byte_array(256) + assert [2, 1] == isre.to_byte_array(258) + else: + assert [1, 0, 0, ] == isre.to_byte_array(1) + assert [0, 1, 0, 0] == isre.to_byte_array(256) + assert [4, 3, 2, 1] == isre.to_byte_array(0x01020304) From tismer at codespeak.net Tue Aug 23 15:24:10 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 15:24:10 +0200 (CEST) Subject: [pypy-svn] r16267 - in pypy/dist/pypy: module/marshal objspace/std Message-ID: <20050823132410.8FCD827B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 15:24:08 2005 New Revision: 16267 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py pypy/dist/pypy/objspace/std/marshal_impl.py Log: support for 2.4.1 compatible way of storing strings for code objects Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Tue Aug 23 15:24:08 2005 @@ -395,6 +395,10 @@ lng = self.get_lng() return self.get(lng) + def atom_lng(self, typecode): + self.start(typecode) + return self.get_lng() + def atom_strlist(self, typecode, tc2): self.start(typecode) lng = self.get_lng() Modified: pypy/dist/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/dist/pypy/objspace/std/marshal_impl.py (original) +++ pypy/dist/pypy/objspace/std/marshal_impl.py Tue Aug 23 15:24:08 2005 @@ -376,34 +376,55 @@ m.atom_str(TYPE_STRING, x.co_code) m.start(TYPE_TUPLE) m.put_list_w(x.co_consts_w, len(x.co_consts_w)) - m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_names) - m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_varnames) - m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_freevars) - m.atom_strlist(TYPE_TUPLE, TYPE_STRING, x.co_cellvars) - m.atom_str(TYPE_STRING, x.co_filename) - m.atom_str(TYPE_STRING, x.co_name) + m.atom_strlist(TYPE_TUPLE, TYPE_INTERNED, x.co_names) + m.atom_strlist(TYPE_TUPLE, TYPE_INTERNED, x.co_varnames) + m.atom_strlist(TYPE_TUPLE, TYPE_INTERNED, x.co_freevars) + m.atom_strlist(TYPE_TUPLE, TYPE_INTERNED, x.co_cellvars) + m.atom_str(TYPE_INTERNED, x.co_filename) + m.atom_str(TYPE_INTERNED, x.co_name) m.put_int(x.co_firstlineno) m.atom_str(TYPE_STRING, x.co_lnotab) StdObjSpace.MM.marshal_w.register(marshal_w_pycode, PyCode) +# helper for unmarshalling string lists of code objects. +# unfortunately they now can be interned or referenced, +# so we no longer can handle it in interp_marshal.atom_strlist + +def unmarshal_str(u): + w_obj = u.get_w_obj(False) + try: + return u.space.str_w(w_obj) + except OperationError: + u.raise_exc('invalid marshal data for code object') + +def unmarshal_strlist(u, tc): + lng = u.atom_lng(tc) + res = [None] * lng + idx = 0 + space = u.space + while idx < lng: + res[idx] = unmarshal_str(u) + idx += 1 + return res + def unmarshal_pycode(space, u, tc): code = PyCode(space) code.co_argcount = u.get_int() code.co_nlocals = u.get_int() code.co_stacksize = u.get_int() code.co_flags = u.get_int() - code.co_code = u.atom_str(TYPE_STRING) + code.co_code = unmarshal_str(u) u.start(TYPE_TUPLE) code.co_consts_w = u.get_list_w() - code.co_names = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) - code.co_varnames = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) - code.co_freevars = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) - code.co_cellvars = u.atom_strlist(TYPE_TUPLE, TYPE_STRING) - code.co_filename = u.atom_str(TYPE_STRING) - code.co_name = u.atom_str(TYPE_STRING) + code.co_names = unmarshal_strlist(u, TYPE_TUPLE) + code.co_varnames = unmarshal_strlist(u, TYPE_TUPLE) + code.co_freevars = unmarshal_strlist(u, TYPE_TUPLE) + code.co_cellvars = unmarshal_strlist(u, TYPE_TUPLE) + code.co_filename = unmarshal_str(u) + code.co_name = unmarshal_str(u) code.co_firstlineno = u.get_int() - code.co_lnotab = u.atom_str(TYPE_STRING) + code.co_lnotab = unmarshal_str(u) return space.wrap(code) register(TYPE_CODE, unmarshal_pycode) From tismer at codespeak.net Tue Aug 23 15:59:33 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 15:59:33 +0200 (CEST) Subject: [pypy-svn] r16268 - in pypy/dist/pypy: fakecompiler interpreter interpreter/pyparser Message-ID: <20050823135933.B0BDC27B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 15:59:27 2005 New Revision: 16268 Added: pypy/dist/pypy/fakecompiler/ pypy/dist/pypy/fakecompiler/fakecompiler.py (contents, props changed) pypy/dist/pypy/fakecompiler/readme.txt (contents, props changed) pypy/dist/pypy/interpreter/pyparser/symbol.py (contents, props changed) Modified: pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyparser/pysymbol.py Log: added a compiler faking feature in order to support quicker testing using the compiled pypy. Run your binary from the fakecompiler folder; please the readme.txt file, first! Added: pypy/dist/pypy/fakecompiler/fakecompiler.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/fakecompiler/fakecompiler.py Tue Aug 23 15:59:27 2005 @@ -0,0 +1,29 @@ +import parser, marshal, os + +DUMPFILE = 'this_is_the_marshal_file' + +def fakeapplevelcompile(tuples, filename, mode): + done = False + data = marshal.dumps( (tuples, filename, mode, done) ) + file(DUMPFILE, "wb").write(data) + os.system('%s fakecompiler.py' % get_python()) + data = file(DUMPFILE, "rb").read() + code, filename, mode, done = marshal.loads(data) + if not done: + raise ValueError, "could not fake compile!" + return code + +def reallycompile(tuples, filename, mode): + return parser.compileast(parser.tuple2ast(tuples), filename) + +def get_python(): + try: + return file('pythonname').read().strip() + except IOError: + raise ValueError, "I need a local file 'pythonname'" + +if __name__ == '__main__': + tuples, filename, mode, done = marshal.load(file(DUMPFILE, "rb")) + code = reallycompile(tuples, filename, mode) + done = True + marshal.dump( (code, filename, mode, done), file(DUMPFILE, "wb"), 1) Added: pypy/dist/pypy/fakecompiler/readme.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/fakecompiler/readme.txt Tue Aug 23 15:59:27 2005 @@ -0,0 +1,16 @@ +Attention! + +This folder's purpose is to support testing using the compiled PyPy. +At the moment, our applevel compiler is a bit slow to make this +useful. Therefore, this folder exists. + +If the compiled pypy's current directory has a file named +"fakecompiler.py", like this folder, then every compilation +that is either "exec" or "eval" gets compiled using CPython. + +Requirements: + +- this folder must be writable +- there must be a file named "pythonname" which contains the + complete filename of a Python 1.4.2 compatible binary. + Please, add this by hand for your installation. Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 15:59:27 2005 @@ -240,15 +240,26 @@ PythonCompiler.__init__(self, space) debug_print("importing the 'compiler' package at app-level...", newline=False) - self._load_compiler() + self._load_compiler('single') debug_print(" done") - def _load_compiler(self): - # doing this all the time, to allow patching - self.w_applevelcompile = self.space.appexec([], r'''(): - from _stablecompiler import apphook - return apphook.applevelcompile - ''') + def _load_compiler(self, mode): + if mode == 'single': + self.w_applevelcompile = self.space.appexec([], r'''(): + from _stablecompiler import apphook + return apphook.applevelcompile + ''') + else: + self.w_applevelcompile = self.space.appexec([], r'''(): + import os + from _stablecompiler import apphook + if os.path.exists('fakecompiler.py'): + print "faking compiler, because fakecompiler.py is in the current dir" + import fakecompiler + return fakecompiler.fakeapplevelcompile + else: + return apphook.applevelcompile + ''') def compile_parse_result(self, parse_result, filename, mode): space = self.space @@ -268,7 +279,7 @@ w_nested_tuples, space.wrap(source_encoding)]) - self._load_compiler() + self._load_compiler(mode) w_code = space.call_function(self.w_applevelcompile, w_nested_tuples, space.wrap(filename), Modified: pypy/dist/pypy/interpreter/pyparser/pysymbol.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pysymbol.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pysymbol.py Tue Aug 23 15:59:27 2005 @@ -1,27 +1,32 @@ # replacement for the CPython symbol module -from pytoken import N_TOKENS +from pypy.interpreter.pyparser import symbol # try to avoid numeric values conflict with tokens # it's important for CPython, but I'm not so sure it's still # important here -SYMBOL_START = N_TOKENS+30 -del N_TOKENS -_count = SYMBOL_START _anoncount = -10 +_count = 0 sym_name = {} sym_values = {} +for _name, _value in symbol.__dict__.items(): + if type(_value) is type(0): + _count = max(_count, _value) + def add_symbol( sym ): - global _count assert type(sym)==str if not sym_values.has_key( sym ): - val = _count + if hasattr(symbol, sym): + val = getattr(symbol, sym) + else: + global _count + _count += 1 + val = _count sym_values[sym] = val sym_name[val] = sym globals()[sym] = val - _count += 1 return val return sym_values[ sym ] Added: pypy/dist/pypy/interpreter/pyparser/symbol.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/symbol.py Tue Aug 23 15:59:27 2005 @@ -0,0 +1,107 @@ +#! /usr/bin/env python + +"""Non-terminal symbols of Python grammar (from "graminit.h").""" + +# This file is automatically generated; please don't muck it up! +# +# To update the symbols in this file, 'cd' to the top directory of +# the python source tree after building the interpreter and run: +# +# python Lib/symbol.py + +#--start constants-- +single_input = 256 +file_input = 257 +eval_input = 258 +decorator = 259 +decorators = 260 +funcdef = 261 +parameters = 262 +varargslist = 263 +fpdef = 264 +fplist = 265 +stmt = 266 +simple_stmt = 267 +small_stmt = 268 +expr_stmt = 269 +augassign = 270 +print_stmt = 271 +del_stmt = 272 +pass_stmt = 273 +flow_stmt = 274 +break_stmt = 275 +continue_stmt = 276 +return_stmt = 277 +yield_stmt = 278 +raise_stmt = 279 +import_stmt = 280 +import_name = 281 +import_from = 282 +import_as_name = 283 +dotted_as_name = 284 +import_as_names = 285 +dotted_as_names = 286 +dotted_name = 287 +global_stmt = 288 +exec_stmt = 289 +assert_stmt = 290 +compound_stmt = 291 +if_stmt = 292 +while_stmt = 293 +for_stmt = 294 +try_stmt = 295 +except_clause = 296 +suite = 297 +test = 298 +and_test = 299 +not_test = 300 +comparison = 301 +comp_op = 302 +expr = 303 +xor_expr = 304 +and_expr = 305 +shift_expr = 306 +arith_expr = 307 +term = 308 +factor = 309 +power = 310 +atom = 311 +listmaker = 312 +testlist_gexp = 313 +lambdef = 314 +trailer = 315 +subscriptlist = 316 +subscript = 317 +sliceop = 318 +exprlist = 319 +testlist = 320 +testlist_safe = 321 +dictmaker = 322 +classdef = 323 +arglist = 324 +argument = 325 +list_iter = 326 +list_for = 327 +list_if = 328 +gen_iter = 329 +gen_for = 330 +gen_if = 331 +testlist1 = 332 +encoding_decl = 333 +#--end constants-- + +sym_name = {} +for _name, _value in globals().items(): + if type(_value) is type(0): + sym_name[_value] = _name + + +def main(): + import sys + import token + if len(sys.argv) == 1: + sys.argv = sys.argv + ["Include/graminit.h", "Lib/symbol.py"] + token.main() + +if __name__ == "__main__": + main() From tismer at codespeak.net Tue Aug 23 16:11:44 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 16:11:44 +0200 (CEST) Subject: [pypy-svn] r16270 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050823141144.A6E6C27B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 16:11:43 2005 New Revision: 16270 Modified: pypy/dist/pypy/interpreter/pyparser/symbol.py Log: white space, to get removed, again Modified: pypy/dist/pypy/interpreter/pyparser/symbol.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/symbol.py (original) +++ pypy/dist/pypy/interpreter/pyparser/symbol.py Tue Aug 23 16:11:43 2005 @@ -1,5 +1,5 @@ #! /usr/bin/env python - + """Non-terminal symbols of Python grammar (from "graminit.h").""" # This file is automatically generated; please don't muck it up! From ludal at codespeak.net Tue Aug 23 16:13:13 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 16:13:13 +0200 (CEST) Subject: [pypy-svn] r16271 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20050823141313.6D54727B41@code1.codespeak.net> Author: ludal Date: Tue Aug 23 16:13:12 2005 New Revision: 16271 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/ast.txt pypy/dist/pypy/interpreter/astcompiler/astgen.py Log: Regenerated ast.py: - name->varname needs a different attribute name to be rpython - make lineno a base attribute of Node - make getChildNodes return list of nodes Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Tue Aug 23 16:13:12 2005 @@ -22,6 +22,9 @@ class Node: """Abstract base class for ast nodes.""" + def __init__(self, lineno = None): + self.lineno = lineno + def getChildren(self): pass # implemented by subclasses def __iter__(self): @@ -30,9 +33,18 @@ def asList(self): # for backwards compatibility return self.getChildren() def getChildNodes(self): - pass # implemented by subclasses + return [] # implemented by subclasses def visit(self, visitor, *args): return visitor.visitNode(self, *args) + def flatten(self): + res = [] + nodes = self.getChildNodes() + if nodes: + for n in nodes: + res.extend( n.flatten() ) + else: + res.append( self ) + return res class EmptyNode(Node): def visit(self, visitor, *args): @@ -42,13 +54,14 @@ # Expression is an artificial node class to support "eval" nodes["expression"] = "Expression" def __init__(self, node): + Node.__init__(self) self.node = node def getChildren(self): - return self.node, + return [self.node,] def getChildNodes(self): - return self.node, + return [self.node,] def __repr__(self): return "Expression(%s)" % (repr(self.node)) @@ -58,15 +71,15 @@ class Add(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "Add((%s, %s))" % (repr(self.left), repr(self.right)) @@ -76,8 +89,8 @@ class And(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -85,7 +98,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "And(%s)" % (repr(self.nodes),) @@ -95,16 +108,16 @@ class AssAttr(Node): def __init__(self, expr, attrname, flags, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.attrname = attrname self.flags = flags - self.lineno = lineno def getChildren(self): return self.expr, self.attrname, self.flags def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) @@ -114,8 +127,8 @@ class AssList(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -123,7 +136,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "AssList(%s)" % (repr(self.nodes),) @@ -133,15 +146,15 @@ class AssName(Node): def __init__(self, name, flags, lineno=None): + Node.__init__(self, lineno) self.name = name self.flags = flags - self.lineno = lineno def getChildren(self): return self.name, self.flags def getChildNodes(self): - return () + return [] def __repr__(self): return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) @@ -151,8 +164,8 @@ class AssTuple(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -160,7 +173,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "AssTuple(%s)" % (repr(self.nodes),) @@ -170,9 +183,9 @@ class Assert(Node): def __init__(self, test, fail, lineno=None): + Node.__init__(self, lineno) self.test = test self.fail = fail - self.lineno = lineno def getChildren(self): children = [] @@ -185,7 +198,7 @@ nodelist.append(self.test) if self.fail is not None: nodelist.append(self.fail) - return tuple(nodelist) + return nodelist def __repr__(self): return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) @@ -195,9 +208,9 @@ class Assign(Node): def __init__(self, nodes, expr, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes self.expr = expr - self.lineno = lineno def getChildren(self): children = [] @@ -209,7 +222,7 @@ nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) nodelist.append(self.expr) - return tuple(nodelist) + return nodelist def __repr__(self): return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) @@ -219,16 +232,16 @@ class AugAssign(Node): def __init__(self, node, op, expr, lineno=None): + Node.__init__(self, lineno) self.node = node self.op = op self.expr = expr - self.lineno = lineno def getChildren(self): return self.node, self.op, self.expr def getChildNodes(self): - return self.node, self.expr + return [self.node, self.expr] def __repr__(self): return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) @@ -238,14 +251,14 @@ class Backquote(Node): def __init__(self, expr, lineno=None): + Node.__init__(self, lineno) self.expr = expr - self.lineno = lineno def getChildren(self): return self.expr, def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "Backquote(%s)" % (repr(self.expr),) @@ -255,8 +268,8 @@ class Bitand(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -264,7 +277,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Bitand(%s)" % (repr(self.nodes),) @@ -274,8 +287,8 @@ class Bitor(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -283,7 +296,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Bitor(%s)" % (repr(self.nodes),) @@ -293,8 +306,8 @@ class Bitxor(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -302,7 +315,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Bitxor(%s)" % (repr(self.nodes),) @@ -312,7 +325,7 @@ class Break(Node): def __init__(self, lineno=None): - self.lineno = lineno + Node.__init__(self, lineno) def getChildren(self): return () @@ -328,11 +341,11 @@ class CallFunc(Node): def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None): + Node.__init__(self, lineno) self.node = node self.args = args self.star_args = star_args self.dstar_args = dstar_args - self.lineno = lineno def getChildren(self): children = [] @@ -350,7 +363,7 @@ nodelist.append(self.star_args) if self.dstar_args is not None: nodelist.append(self.dstar_args) - return tuple(nodelist) + return nodelist def __repr__(self): return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) @@ -360,11 +373,11 @@ class Class(Node): def __init__(self, name, bases, doc, code, lineno=None): + Node.__init__(self, lineno) self.name = name self.bases = bases self.doc = doc self.code = code - self.lineno = lineno def getChildren(self): children = [] @@ -378,7 +391,7 @@ nodelist = [] nodelist.extend(flatten_nodes(self.bases)) nodelist.append(self.code) - return tuple(nodelist) + return nodelist def __repr__(self): return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code)) @@ -388,9 +401,9 @@ class Compare(Node): def __init__(self, expr, ops, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.ops = ops - self.lineno = lineno def getChildren(self): children = [] @@ -402,7 +415,7 @@ nodelist = [] nodelist.append(self.expr) nodelist.extend(flatten_nodes(self.ops)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) @@ -412,14 +425,14 @@ class Const(Node): def __init__(self, value, lineno=None): + Node.__init__(self, lineno) self.value = value - self.lineno = lineno def getChildren(self): return self.value, def getChildNodes(self): - return () + return [] def __repr__(self): return "Const(%s)" % (repr(self.value),) @@ -429,7 +442,7 @@ class Continue(Node): def __init__(self, lineno=None): - self.lineno = lineno + Node.__init__(self, lineno) def getChildren(self): return () @@ -445,8 +458,8 @@ class Decorators(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -454,7 +467,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Decorators(%s)" % (repr(self.nodes),) @@ -464,8 +477,8 @@ class Dict(Node): def __init__(self, items, lineno=None): + Node.__init__(self, lineno) self.items = items - self.lineno = lineno def getChildren(self): return tuple(flatten(self.items)) @@ -473,7 +486,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.items)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Dict(%s)" % (repr(self.items),) @@ -483,14 +496,14 @@ class Discard(Node): def __init__(self, expr, lineno=None): + Node.__init__(self, lineno) self.expr = expr - self.lineno = lineno def getChildren(self): return self.expr, def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "Discard(%s)" % (repr(self.expr),) @@ -500,15 +513,15 @@ class Div(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "Div((%s, %s))" % (repr(self.left), repr(self.right)) @@ -518,7 +531,7 @@ class Ellipsis(Node): def __init__(self, lineno=None): - self.lineno = lineno + Node.__init__(self, lineno) def getChildren(self): return () @@ -534,10 +547,10 @@ class Exec(Node): def __init__(self, expr, locals, globals, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.locals = locals self.globals = globals - self.lineno = lineno def getChildren(self): children = [] @@ -553,7 +566,7 @@ nodelist.append(self.locals) if self.globals is not None: nodelist.append(self.globals) - return tuple(nodelist) + return nodelist def __repr__(self): return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) @@ -563,15 +576,15 @@ class FloorDiv(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) @@ -581,11 +594,11 @@ class For(Node): def __init__(self, assign, list, body, else_, lineno=None): + Node.__init__(self, lineno) self.assign = assign self.list = list self.body = body self.else_ = else_ - self.lineno = lineno def getChildren(self): children = [] @@ -602,7 +615,7 @@ nodelist.append(self.body) if self.else_ is not None: nodelist.append(self.else_) - return tuple(nodelist) + return nodelist def __repr__(self): return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) @@ -612,15 +625,15 @@ class From(Node): def __init__(self, modname, names, lineno=None): + Node.__init__(self, lineno) self.modname = modname self.names = names - self.lineno = lineno def getChildren(self): return self.modname, self.names def getChildNodes(self): - return () + return [] def __repr__(self): return "From(%s, %s)" % (repr(self.modname), repr(self.names)) @@ -630,6 +643,7 @@ class Function(Node): def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None): + Node.__init__(self, lineno) self.decorators = decorators self.name = name self.argnames = argnames @@ -637,7 +651,6 @@ self.flags = flags self.doc = doc self.code = code - self.lineno = lineno self.varargs = self.kwargs = None if flags & CO_VARARGS: self.varargs = 1 @@ -663,7 +676,7 @@ nodelist.append(self.decorators) nodelist.extend(flatten_nodes(self.defaults)) nodelist.append(self.code) - return tuple(nodelist) + return nodelist def __repr__(self): return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) @@ -673,8 +686,8 @@ class GenExpr(Node): def __init__(self, code, lineno=None): + Node.__init__(self, lineno) self.code = code - self.lineno = lineno self.argnames = ['[outmost-iterable]'] self.varargs = self.kwargs = None @@ -684,7 +697,7 @@ return self.code, def getChildNodes(self): - return self.code, + return [self.code,] def __repr__(self): return "GenExpr(%s)" % (repr(self.code),) @@ -694,10 +707,10 @@ class GenExprFor(Node): def __init__(self, assign, iter, ifs, lineno=None): + Node.__init__(self, lineno) self.assign = assign self.iter = iter self.ifs = ifs - self.lineno = lineno self.is_outmost = False @@ -713,7 +726,7 @@ nodelist.append(self.assign) nodelist.append(self.iter) nodelist.extend(flatten_nodes(self.ifs)) - return tuple(nodelist) + return nodelist def __repr__(self): return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) @@ -723,14 +736,14 @@ class GenExprIf(Node): def __init__(self, test, lineno=None): + Node.__init__(self, lineno) self.test = test - self.lineno = lineno def getChildren(self): return self.test, def getChildNodes(self): - return self.test, + return [self.test,] def __repr__(self): return "GenExprIf(%s)" % (repr(self.test),) @@ -740,9 +753,9 @@ class GenExprInner(Node): def __init__(self, expr, quals, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.quals = quals - self.lineno = lineno def getChildren(self): children = [] @@ -754,7 +767,7 @@ nodelist = [] nodelist.append(self.expr) nodelist.extend(flatten_nodes(self.quals)) - return tuple(nodelist) + return nodelist def __repr__(self): return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) @@ -764,15 +777,15 @@ class Getattr(Node): def __init__(self, expr, attrname, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.attrname = attrname - self.lineno = lineno def getChildren(self): return self.expr, self.attrname def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) @@ -782,14 +795,14 @@ class Global(Node): def __init__(self, names, lineno=None): + Node.__init__(self, lineno) self.names = names - self.lineno = lineno def getChildren(self): return self.names, def getChildNodes(self): - return () + return [] def __repr__(self): return "Global(%s)" % (repr(self.names),) @@ -799,9 +812,9 @@ class If(Node): def __init__(self, tests, else_, lineno=None): + Node.__init__(self, lineno) self.tests = tests self.else_ = else_ - self.lineno = lineno def getChildren(self): children = [] @@ -814,7 +827,7 @@ nodelist.extend(flatten_nodes(self.tests)) if self.else_ is not None: nodelist.append(self.else_) - return tuple(nodelist) + return nodelist def __repr__(self): return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) @@ -824,14 +837,14 @@ class Import(Node): def __init__(self, names, lineno=None): + Node.__init__(self, lineno) self.names = names - self.lineno = lineno def getChildren(self): return self.names, def getChildNodes(self): - return () + return [] def __repr__(self): return "Import(%s)" % (repr(self.names),) @@ -841,14 +854,14 @@ class Invert(Node): def __init__(self, expr, lineno=None): + Node.__init__(self, lineno) self.expr = expr - self.lineno = lineno def getChildren(self): return self.expr, def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "Invert(%s)" % (repr(self.expr),) @@ -858,15 +871,15 @@ class Keyword(Node): def __init__(self, name, expr, lineno=None): + Node.__init__(self, lineno) self.name = name self.expr = expr - self.lineno = lineno def getChildren(self): return self.name, self.expr def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) @@ -876,11 +889,11 @@ class Lambda(Node): def __init__(self, argnames, defaults, flags, code, lineno=None): + Node.__init__(self, lineno) self.argnames = argnames self.defaults = defaults self.flags = flags self.code = code - self.lineno = lineno self.varargs = self.kwargs = None if flags & CO_VARARGS: self.varargs = 1 @@ -901,7 +914,7 @@ nodelist = [] nodelist.extend(flatten_nodes(self.defaults)) nodelist.append(self.code) - return tuple(nodelist) + return nodelist def __repr__(self): return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) @@ -911,15 +924,15 @@ class LeftShift(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) @@ -929,8 +942,8 @@ class List(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -938,7 +951,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "List(%s)" % (repr(self.nodes),) @@ -948,9 +961,9 @@ class ListComp(Node): def __init__(self, expr, quals, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.quals = quals - self.lineno = lineno def getChildren(self): children = [] @@ -962,7 +975,7 @@ nodelist = [] nodelist.append(self.expr) nodelist.extend(flatten_nodes(self.quals)) - return tuple(nodelist) + return nodelist def __repr__(self): return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) @@ -972,10 +985,10 @@ class ListCompFor(Node): def __init__(self, assign, list, ifs, lineno=None): + Node.__init__(self, lineno) self.assign = assign self.list = list self.ifs = ifs - self.lineno = lineno def getChildren(self): children = [] @@ -989,7 +1002,7 @@ nodelist.append(self.assign) nodelist.append(self.list) nodelist.extend(flatten_nodes(self.ifs)) - return tuple(nodelist) + return nodelist def __repr__(self): return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) @@ -999,14 +1012,14 @@ class ListCompIf(Node): def __init__(self, test, lineno=None): + Node.__init__(self, lineno) self.test = test - self.lineno = lineno def getChildren(self): return self.test, def getChildNodes(self): - return self.test, + return [self.test,] def __repr__(self): return "ListCompIf(%s)" % (repr(self.test),) @@ -1016,15 +1029,15 @@ class Mod(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) @@ -1034,15 +1047,15 @@ class Module(Node): def __init__(self, doc, node, lineno=None): + Node.__init__(self, lineno) self.doc = doc self.node = node - self.lineno = lineno def getChildren(self): return self.doc, self.node def getChildNodes(self): - return self.node, + return [self.node,] def __repr__(self): return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) @@ -1052,15 +1065,15 @@ class Mul(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) @@ -1069,16 +1082,15 @@ return visitor.visitMul(self, args) class Name(Node): - def __init__(self, name, lineno=None): - # self.name = name - self.varname = name - self.lineno = lineno + def __init__(self, varname, lineno=None): + Node.__init__(self, lineno) + self.varname = varname def getChildren(self): return self.varname, def getChildNodes(self): - return () + return [] def __repr__(self): return "Name(%s)" % (repr(self.varname),) @@ -1088,14 +1100,14 @@ class Not(Node): def __init__(self, expr, lineno=None): + Node.__init__(self, lineno) self.expr = expr - self.lineno = lineno def getChildren(self): return self.expr, def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "Not(%s)" % (repr(self.expr),) @@ -1105,8 +1117,8 @@ class Or(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -1114,7 +1126,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Or(%s)" % (repr(self.nodes),) @@ -1124,7 +1136,7 @@ class Pass(Node): def __init__(self, lineno=None): - self.lineno = lineno + Node.__init__(self, lineno) def getChildren(self): return () @@ -1140,15 +1152,15 @@ class Power(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "Power((%s, %s))" % (repr(self.left), repr(self.right)) @@ -1158,9 +1170,9 @@ class Print(Node): def __init__(self, nodes, dest, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes self.dest = dest - self.lineno = lineno def getChildren(self): children = [] @@ -1173,7 +1185,7 @@ nodelist.extend(flatten_nodes(self.nodes)) if self.dest is not None: nodelist.append(self.dest) - return tuple(nodelist) + return nodelist def __repr__(self): return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) @@ -1183,9 +1195,9 @@ class Printnl(Node): def __init__(self, nodes, dest, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes self.dest = dest - self.lineno = lineno def getChildren(self): children = [] @@ -1198,7 +1210,7 @@ nodelist.extend(flatten_nodes(self.nodes)) if self.dest is not None: nodelist.append(self.dest) - return tuple(nodelist) + return nodelist def __repr__(self): return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) @@ -1208,10 +1220,10 @@ class Raise(Node): def __init__(self, expr1, expr2, expr3, lineno=None): + Node.__init__(self, lineno) self.expr1 = expr1 self.expr2 = expr2 self.expr3 = expr3 - self.lineno = lineno def getChildren(self): children = [] @@ -1228,7 +1240,7 @@ nodelist.append(self.expr2) if self.expr3 is not None: nodelist.append(self.expr3) - return tuple(nodelist) + return nodelist def __repr__(self): return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) @@ -1238,14 +1250,14 @@ class Return(Node): def __init__(self, value, lineno=None): + Node.__init__(self, lineno) self.value = value - self.lineno = lineno def getChildren(self): return self.value, def getChildNodes(self): - return self.value, + return [self.value,] def __repr__(self): return "Return(%s)" % (repr(self.value),) @@ -1255,15 +1267,15 @@ class RightShift(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) @@ -1273,11 +1285,11 @@ class Slice(Node): def __init__(self, expr, flags, lower, upper, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.flags = flags self.lower = lower self.upper = upper - self.lineno = lineno def getChildren(self): children = [] @@ -1294,7 +1306,7 @@ nodelist.append(self.lower) if self.upper is not None: nodelist.append(self.upper) - return tuple(nodelist) + return nodelist def __repr__(self): return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) @@ -1304,8 +1316,8 @@ class Sliceobj(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -1313,7 +1325,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Sliceobj(%s)" % (repr(self.nodes),) @@ -1323,8 +1335,8 @@ class Stmt(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -1332,7 +1344,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Stmt(%s)" % (repr(self.nodes),) @@ -1342,15 +1354,15 @@ class Sub(Node): def __init__(self, (left, right), lineno=None): + Node.__init__(self, lineno) self.left = left self.right = right - self.lineno = lineno def getChildren(self): return self.left, self.right def getChildNodes(self): - return self.left, self.right + return [self.left, self.right] def __repr__(self): return "Sub((%s, %s))" % (repr(self.left), repr(self.right)) @@ -1360,10 +1372,10 @@ class Subscript(Node): def __init__(self, expr, flags, subs, lineno=None): + Node.__init__(self, lineno) self.expr = expr self.flags = flags self.subs = subs - self.lineno = lineno def getChildren(self): children = [] @@ -1376,7 +1388,7 @@ nodelist = [] nodelist.append(self.expr) nodelist.extend(flatten_nodes(self.subs)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) @@ -1386,10 +1398,10 @@ class TryExcept(Node): def __init__(self, body, handlers, else_, lineno=None): + Node.__init__(self, lineno) self.body = body self.handlers = handlers self.else_ = else_ - self.lineno = lineno def getChildren(self): children = [] @@ -1404,7 +1416,7 @@ nodelist.extend(flatten_nodes(self.handlers)) if self.else_ is not None: nodelist.append(self.else_) - return tuple(nodelist) + return nodelist def __repr__(self): return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) @@ -1414,15 +1426,15 @@ class TryFinally(Node): def __init__(self, body, final, lineno=None): + Node.__init__(self, lineno) self.body = body self.final = final - self.lineno = lineno def getChildren(self): return self.body, self.final def getChildNodes(self): - return self.body, self.final + return [self.body, self.final] def __repr__(self): return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) @@ -1432,8 +1444,8 @@ class Tuple(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self, lineno) self.nodes = nodes - self.lineno = lineno def getChildren(self): return tuple(flatten(self.nodes)) @@ -1441,7 +1453,7 @@ def getChildNodes(self): nodelist = [] nodelist.extend(flatten_nodes(self.nodes)) - return tuple(nodelist) + return nodelist def __repr__(self): return "Tuple(%s)" % (repr(self.nodes),) @@ -1451,14 +1463,14 @@ class UnaryAdd(Node): def __init__(self, expr, lineno=None): + Node.__init__(self, lineno) self.expr = expr - self.lineno = lineno def getChildren(self): return self.expr, def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "UnaryAdd(%s)" % (repr(self.expr),) @@ -1468,14 +1480,14 @@ class UnarySub(Node): def __init__(self, expr, lineno=None): + Node.__init__(self, lineno) self.expr = expr - self.lineno = lineno def getChildren(self): return self.expr, def getChildNodes(self): - return self.expr, + return [self.expr,] def __repr__(self): return "UnarySub(%s)" % (repr(self.expr),) @@ -1485,10 +1497,10 @@ class While(Node): def __init__(self, test, body, else_, lineno=None): + Node.__init__(self, lineno) self.test = test self.body = body self.else_ = else_ - self.lineno = lineno def getChildren(self): children = [] @@ -1503,7 +1515,7 @@ nodelist.append(self.body) if self.else_ is not None: nodelist.append(self.else_) - return tuple(nodelist) + return nodelist def __repr__(self): return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) @@ -1513,14 +1525,14 @@ class Yield(Node): def __init__(self, value, lineno=None): + Node.__init__(self, lineno) self.value = value - self.lineno = lineno def getChildren(self): return self.value, def getChildNodes(self): - return self.value, + return [self.value,] def __repr__(self): return "Yield(%s)" % (repr(self.value),) Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.txt (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.txt Tue Aug 23 16:13:12 2005 @@ -47,7 +47,7 @@ Dict: items! Not: expr Compare: expr, ops! -Name: name* +Name: varname* Global: names* Backquote: expr Getattr: expr, attrname* Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Tue Aug 23 16:13:12 2005 @@ -113,10 +113,10 @@ print >> buf, " def __init__(self, %s, lineno=None):" % self.args else: print >> buf, " def __init__(self, lineno=None):" + print >> buf, " Node.__init__(self, lineno)" if self.argnames: for name in self.argnames: print >> buf, " self.%s = %s" % (name, name) - print >> buf, " self.lineno = lineno" if self.init: print >> buf, "".join([" " + line for line in self.init]) @@ -156,11 +156,11 @@ for c in self.argnames if self.argprops[c] == P_NODE] if len(clist) == 0: - print >> buf, " return ()" + print >> buf, " return []" elif len(clist) == 1: - print >> buf, " return %s," % clist[0] + print >> buf, " return [%s,]" % clist[0] else: - print >> buf, " return %s" % COMMA.join(clist) + print >> buf, " return [%s]" % COMMA.join(clist) else: print >> buf, " nodelist = []" template = " nodelist.%s(%sself.%s%s)" @@ -174,7 +174,7 @@ name, ")") elif self.argprops[name] == P_NODE: print >> buf, template % ("append", "", name, "") - print >> buf, " return tuple(nodelist)" + print >> buf, " return nodelist" def _gen_repr(self, buf): print >> buf, " def __repr__(self):" @@ -285,6 +285,9 @@ class Node: """Abstract base class for ast nodes.""" + def __init__(self, lineno = None): + self.lineno = lineno + def getChildren(self): pass # implemented by subclasses def __iter__(self): @@ -293,9 +296,18 @@ def asList(self): # for backwards compatibility return self.getChildren() def getChildNodes(self): - pass # implemented by subclasses + return [] # implemented by subclasses def visit(self, visitor, *args): return visitor.visitNode(self, *args) + def flatten(self): + res = [] + nodes = self.getChildNodes() + if nodes: + for n in nodes: + res.extend( n.flatten() ) + else: + res.append( self ) + return res class EmptyNode(Node): def visit(self, visitor, *args): @@ -305,13 +317,14 @@ # Expression is an artificial node class to support "eval" nodes["expression"] = "Expression" def __init__(self, node): + Node.__init__(self) self.node = node def getChildren(self): - return self.node, + return [self.node,] def getChildNodes(self): - return self.node, + return [self.node,] def __repr__(self): return "Expression(%s)" % (repr(self.node)) From tismer at codespeak.net Tue Aug 23 16:13:30 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 16:13:30 +0200 (CEST) Subject: [pypy-svn] r16272 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050823141330.E6C9B27B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 16:13:30 2005 New Revision: 16272 Modified: pypy/dist/pypy/interpreter/pyparser/symbol.py Log: this file is identical with the symbol.py file from lib-2.4.1. I needed to add it because we want to use CPython temporarily to compile already-built tuples. Since this file is imported at interpreter level, it was easier to add it than to mangle the import path. Modified: pypy/dist/pypy/interpreter/pyparser/symbol.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/symbol.py (original) +++ pypy/dist/pypy/interpreter/pyparser/symbol.py Tue Aug 23 16:13:30 2005 @@ -1,5 +1,5 @@ #! /usr/bin/env python - + """Non-terminal symbols of Python grammar (from "graminit.h").""" # This file is automatically generated; please don't muck it up! From arigo at codespeak.net Tue Aug 23 16:23:28 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 16:23:28 +0200 (CEST) Subject: [pypy-svn] r16273 - in pypy/dist/pypy/rpython: . test Message-ID: <20050823142328.F00D727B41@code1.codespeak.net> Author: arigo Date: Tue Aug 23 16:23:26 2005 New Revision: 16273 Added: pypy/dist/pypy/rpython/test/test_rexternalobj.py (contents, props changed) Modified: pypy/dist/pypy/rpython/lltype.py pypy/dist/pypy/rpython/rexternalobj.py pypy/dist/pypy/rpython/test/test_lltype.py Log: * Support for prebuilt constants of external type in the RTyper. Useful for prebuilt thread.LockType objects. * Completed the move of lltype.OpaqueType towards inlineability inside structs, with a test. Also tests parentlink(). Modified: pypy/dist/pypy/rpython/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltype.py (original) +++ pypy/dist/pypy/rpython/lltype.py Tue Aug 23 16:23:26 2005 @@ -282,7 +282,7 @@ return _opaque(self) def _defl(self, parent=None, parentindex=None): - return self._container_example() + return _opaque(self, parent=parent, parentindex=parentindex) RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo") @@ -690,12 +690,10 @@ if n is None and TYPE._arrayfld is not None: raise TypeError("%r is variable-sized" % (TYPE,)) for fld, typ in TYPE._flds.items(): - if isinstance(typ, Struct): - value = _struct(typ, parent=self, parentindex=fld) - elif fld == TYPE._arrayfld: + if fld == TYPE._arrayfld: value = _array(typ, n, parent=self, parentindex=fld) else: - value = typ._defl() + value = typ._defl(parent=self, parentindex=fld) setattr(self, fld, value) if parent is not None: self._setparentstructure(parent, parentindex) @@ -783,17 +781,13 @@ def __hash__(self): return hash(frozendict(self.__dict__)) -class _opaque(object): - def __init__(self, TYPE, **attrs): - self._TYPE = TYPE +class _opaque(_parentable): + def __init__(self, TYPE, parent=None, parentindex=None, **attrs): + _parentable.__init__(self, TYPE) self._name = "?" self.__dict__.update(attrs) - - def _parentstructure(self): - return None - - def _check(self): - pass + if parent is not None: + self._setparentstructure(parent, parentindex) def __repr__(self): return '<%s>' % (self,) Modified: pypy/dist/pypy/rpython/rexternalobj.py ============================================================================== --- pypy/dist/pypy/rpython/rexternalobj.py (original) +++ pypy/dist/pypy/rpython/rexternalobj.py Tue Aug 23 16:23:26 2005 @@ -4,6 +4,8 @@ from pypy.rpython.rmodel import Repr from pypy.rpython.extfunctable import typetable from pypy.rpython import rbuiltin +from pypy.rpython.module.support import init_opaque_object +from pypy.objspace.flow.model import Constant from pypy.tool import sourcetools @@ -20,6 +22,7 @@ self.exttypeinfo = typetable[knowntype] TYPE = self.exttypeinfo.get_lltype() self.lowleveltype = lltype.Ptr(TYPE) + self.instance_cache = {} # The set of methods supported depends on 'knowntype', so we # cannot have rtype_method_xxx() methods directly on the # ExternalObjRepr class. But we can store them in 'self' now. @@ -27,3 +30,19 @@ methodname = 'rtype_method_' + name bltintyper = rbuiltin.make_rtype_extfunc(extfuncinfo) setattr(self, methodname, bltintyper) + + def convert_const(self, value): + T = self.exttypeinfo.get_lltype() + if value is None: + return nullptr(T) + if not isinstance(value, self.exttypeinfo.typ): + raise TyperError("expected a %r: %r" % (self.exttypeinfo.typ, + value)) + key = Constant(value) + try: + p = self.instance_cache[key] + except KeyError: + p = lltype.malloc(T) + init_opaque_object(p.obj, value) + self.instance_cache[key] = p + return p Modified: pypy/dist/pypy/rpython/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_lltype.py (original) +++ pypy/dist/pypy/rpython/test/test_lltype.py Tue Aug 23 16:23:26 2005 @@ -396,4 +396,14 @@ assert typeOf(p).TO == S assert not isweak(p, S) - +def test_opaque(): + O = OpaqueType('O') + p1 = opaqueptr(O, 'p1', hello="world") + assert typeOf(p1) == Ptr(O) + assert p1._obj.hello == "world" + assert parentlink(p1._obj) == (None, None) + S = GcStruct('S', ('stuff', O)) + p2 = malloc(S) + assert typeOf(p2) == Ptr(S) + assert typeOf(p2.stuff) == Ptr(O) + assert parentlink(p2.stuff._obj) == (p2._obj, 'stuff') Added: pypy/dist/pypy/rpython/test/test_rexternalobj.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/test/test_rexternalobj.py Tue Aug 23 16:23:26 2005 @@ -0,0 +1,21 @@ +from pypy.rpython.lltype import * +from pypy.rpython.test.test_llinterp import interpret, gengraph +from pypy.annotation.policy import AnnotatorPolicy + +def test_prebuilt_lock(): + import thread + import pypy.module.thread.rpython.exttable # for declare()/declaretype() + lock0 = thread.allocate_lock() + lock1 = thread.allocate_lock() + lock1.acquire() + def fn(i): + lock = [lock0, lock1][i] + ok = lock.acquire(False) + if ok: lock.release() + return ok + policy = AnnotatorPolicy() + policy.allow_someobjects = False + res = interpret(fn, [0], policy=policy) + assert res is True + res = interpret(fn, [1], policy=policy) + assert res is False From hpk at codespeak.net Tue Aug 23 16:27:44 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 16:27:44 +0200 (CEST) Subject: [pypy-svn] r16274 - pypy/dist/pypy/doc Message-ID: <20050823142744.3F56C27B41@code1.codespeak.net> Author: hpk Date: Tue Aug 23 16:27:43 2005 New Revision: 16274 Modified: pypy/dist/pypy/doc/coding-guide.txt pypy/dist/pypy/doc/extradoc.txt pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/news.txt Log: fix a couple of URLs to honour the new locations Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Tue Aug 23 16:27:43 2005 @@ -825,6 +825,7 @@ .. _`testing in PyPy`: +.. _`test-design`: Testing in PyPy =============== Modified: pypy/dist/pypy/doc/extradoc.txt ============================================================================== --- pypy/dist/pypy/doc/extradoc.txt (original) +++ pypy/dist/pypy/doc/extradoc.txt Tue Aug 23 16:27:43 2005 @@ -19,11 +19,11 @@ * `py lib slides`_ from the py lib talk at PyCon 2005 (py is used as a support/testing library for PyPy). -.. _oscon2003-paper: http://codespeak.net/pypy/index.cgi?extradoc/talk/oscon2003-paper.html -.. _`Architecture introduction slides`: http://codespeak.net/svn/pypy/extradoc/talk/amsterdam-sprint-intro.pdf -.. _`EU funding for FOSS`: http://codespeak.net/svn/pypy/extradoc/talk/2004-21C3-pypy-EU-hpk.pdf -.. _`py lib slides`: http://codespeak.net/svn/pypy/extradoc/talk/2005-pycon-py.pdf -.. _`PyCon 2005`: http://codespeak.net/pypy/index.cgi?extradoc/talk/pypy-talk-pycon2005/README.html +.. _oscon2003-paper: http://codespeak.net/pypy/extradoc/talk/oscon2003-paper.html +.. _`Architecture introduction slides`: http://codespeak.net/pypy/extradoc/talk/amsterdam-sprint-intro.pdf +.. _`EU funding for FOSS`: http://codespeak.net/pypy/extradoc/talk/2004-21C3-pypy-EU-hpk.pdf +.. _`py lib slides`: http://codespeak.net/pypy/extradoc/talk/2005-pycon-py.pdf +.. _`PyCon 2005`: http://codespeak.net/pypy/extradoc/talk/pypy-talk-pycon2005/README.html Related projects ---------------------------------- Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Tue Aug 23 16:27:43 2005 @@ -523,7 +523,7 @@ conferences such as EuroPython or Pycon. .. _`pypy-dev mailing list`: http://codespeak.net/mailman/listinfo/pypy-dev -.. _`contact possibilities`: http://codespeak.net/pypy/index.cgi?contact +.. _`contact possibilities`: contact.html .. _`py library`: http://codespeak.net/py .. _`PyPy/LLVM backend`: translation.html#llvm @@ -543,16 +543,15 @@ .. _module.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/module.py .. _mixedmodule.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/mixedmodule.py .. _typedef.py: http://codespeak.net/svn/pypy/dist/pypy/interpreter/typedef.py -.. _Standard object space: http://codespeak.net/pypy/index.cgi?doc/stdobjspace.html -.. _objspace.py: http://codespeak.net/svn/pypy/dist/pypy/objspace/std/objspace.py -.. _thunk: http://codespeak.net/svn/pypy/dist/pypy/objspace/thunk.py -.. _trace: http://codespeak.net/svn/pypy/dist/pypy/objspace/trace.py -.. _flow: http://codespeak.net/svn/pypy/dist/pypy/objspace/flow/ -.. _translator.py: http://codespeak.net/svn/pypy/dist/pypy/translator/translator.py -.. _mailing lists: http://codespeak.net/pypy/index.cgi?lists +.. _Standard object space: objspace.html#the-standard-object-space +.. _objspace.py: http://codespeak.net/pypy/dist/pypy/objspace/std/objspace.py +.. _thunk: http://codespeak.net/pypy/dist/pypy/objspace/thunk.py +.. _trace: http://codespeak.net/pypy/dist/pypy/objspace/trace.py +.. _flow: http://codespeak.net/pypy/dist/pypy/objspace/flow/ +.. _translator.py: http://codespeak.net/pypy/dist/pypy/translator/translator.py +.. _mailing lists: contact.html .. _documentation: index.html -.. _wiki: http://codespeak.net/moin/pypy/moin.cgi/FrontPage?action=show -.. _unit tests: http://codespeak.net/pypy/index.cgi?doc/testdesign.html +.. _unit tests: coding-guide.html#test-design .. _bug reports: https://codespeak.net/issue/pypy-dev/ .. _`directory reference`: index.html#directory-reference Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Tue Aug 23 16:27:43 2005 @@ -83,5 +83,5 @@ `release announcement`_. *(05/20/2005)* .. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.6.html -.. _`getting started`: http://codespeak.net/pypy/pypy/dist/pypy/doc/getting-started +.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html From hpk at codespeak.net Tue Aug 23 16:30:14 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 16:30:14 +0200 (CEST) Subject: [pypy-svn] r16275 - pypy/dist/pypy/doc Message-ID: <20050823143014.256DF27B41@code1.codespeak.net> Author: hpk Date: Tue Aug 23 16:30:12 2005 New Revision: 16275 Added: pypy/dist/pypy/doc/parser.txt - copied, changed from r16274, pypy/dist/pypy/doc/parser-design.txt Removed: pypy/dist/pypy/doc/parser-design.txt Modified: pypy/dist/pypy/doc/index.txt pypy/dist/pypy/doc/misc.txt Log: some more link fixing and renamed parser-design to parser and linked it from the home page Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Tue Aug 23 16:30:12 2005 @@ -20,6 +20,9 @@ `translation`_ offers the beginnings of documentation about our low level code generator backends. +`parser`_ contains the beginnings of documentation about +the parser (and the compiler at some point). + `talks and related projects`_ lists presentations and related projects. @@ -28,6 +31,7 @@ `license`_ contains licensing details (basically a straight MIT-license). +.. _parser: parser.html .. _`talks and related projects`: extradoc.html .. _`license`: http://codespeak.net/svn/pypy/dist/LICENSE .. _`compliance test status`: http://codespeak.net/~hpk/pypy-testresult/ Modified: pypy/dist/pypy/doc/misc.txt ============================================================================== --- pypy/dist/pypy/doc/misc.txt (original) +++ pypy/dist/pypy/doc/misc.txt Tue Aug 23 16:30:12 2005 @@ -584,7 +584,7 @@ - Port the built-in Python library to PyPy (functions, types and modules currently implemented in C) -- types needs refactoring, the rest is mostly done. Anthony Baxter has given us a very useful - list of the cmodules_ we need to consider porting. + list of the cmodules [link missing] we need to consider porting. - Decide on a case-by-case basis which features are to be implemented using RPython or just general Python. -- moving target. @@ -709,6 +709,3 @@ - Make a build- and configuration tool that allows to build custom PyPy versions suitable for specialized environments such as small or very large computing devices. - -.. _cmodules: http://codespeak.net/pypy/index.cgi?doc/cmodules.html - From ac at codespeak.net Tue Aug 23 16:33:07 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 23 Aug 2005 16:33:07 +0200 (CEST) Subject: [pypy-svn] r16276 - pypy/dist/lib-python Message-ID: <20050823143307.1269027B41@code1.codespeak.net> Author: ac Date: Tue Aug 23 16:33:05 2005 New Revision: 16276 Modified: pypy/dist/lib-python/conftest.py Log: Enable the core tests. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Aug 23 16:33:05 2005 @@ -355,7 +355,7 @@ ''') testmap = [ - RegrTest('test___all__.py', enabled=False, core=True), + RegrTest('test___all__.py', enabled=True, core=True), # fixable RegrTest('test___future__.py', enabled=True, dumbtest=1, core=True), RegrTest('test__locale.py', enabled=True), @@ -365,7 +365,7 @@ RegrTest('test_applesingle.py', enabled=False), RegrTest('test_array.py', enabled=True, core=True), RegrTest('test_asynchat.py', enabled=False), - RegrTest('test_atexit.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_atexit.py', enabled=True, dumbtest=1, core=True), RegrTest('test_audioop.py', enabled=False, dumbtest=1), RegrTest('test_augassign.py', enabled=True, core=True), RegrTest('test_base64.py', enabled=True), @@ -382,7 +382,7 @@ RegrTest('test_bsddb.py', enabled=False), RegrTest('test_bsddb185.py', enabled=False), RegrTest('test_bsddb3.py', enabled=False), - RegrTest('test_bufio.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_bufio.py', enabled=True, dumbtest=1, core=True), RegrTest('test_builtin.py', enabled=True, core=True), RegrTest('test_bz2.py', enabled=False), RegrTest('test_calendar.py', enabled=True), @@ -398,10 +398,9 @@ RegrTest('test_cgi.py', enabled=True), RegrTest('test_charmapcodec.py', enabled=True, core=True), RegrTest('test_cl.py', enabled=False, dumbtest=1), - RegrTest('test_class.py', enabled=False, oldstyle=True, core=True), + RegrTest('test_class.py', enabled=True, oldstyle=True, core=True), RegrTest('test_cmath.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_codeccallbacks.py', enabled=False, core=True), - #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser + RegrTest('test_codeccallbacks.py', enabled=True, core=True), RegrTest('test_codecencodings_cn.py', enabled=False), RegrTest('test_codecencodings_hk.py', enabled=False), RegrTest('test_codecencodings_jp.py', enabled=False), @@ -413,28 +412,23 @@ RegrTest('test_codecmaps_jp.py', enabled=False), RegrTest('test_codecmaps_kr.py', enabled=False), RegrTest('test_codecmaps_tw.py', enabled=False), - - RegrTest('test_codecs.py', enabled=False, core=True), - #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser - + RegrTest('test_codecs.py', enabled=True, core=True), RegrTest('test_codeop.py', enabled=True, core=True), - RegrTest('test_coercion.py', enabled=False, oldstyle=True, core=True), - # needed changes because our exceptions are new-style and so have a different str(.) behavior + RegrTest('test_coercion.py', enabled=True, oldstyle=True, core=True), RegrTest('test_colorsys.py', enabled=True), RegrTest('test_commands.py', enabled=True), RegrTest('test_compare.py', enabled=True, oldstyle=True, core=True), RegrTest('test_compile.py', enabled=True, core=True), RegrTest('test_compiler.py', enabled=True, core=True), - RegrTest('test_complex.py', enabled=False, core=True), - #rev 10840: at least one test fails, after several hours I gave up waiting for the rest + RegrTest('test_complex.py', enabled=True, core=True), RegrTest('test_contains.py', enabled=True, dumbtest=1, core=True), RegrTest('test_cookie.py', enabled=False), RegrTest('test_cookielib.py', enabled=False), RegrTest('test_copy.py', enabled=True, core=True), RegrTest('test_copy_reg.py', enabled=True, core=True), - RegrTest('test_cpickle.py', enabled=False, core=True), + RegrTest('test_cpickle.py', enabled=True, core=True), RegrTest('test_crypt.py', enabled=False, dumbtest=1), RegrTest('test_csv.py', enabled=False), #rev 10840: ImportError: _csv @@ -445,8 +439,8 @@ RegrTest('test_decimal.py', enabled=True), RegrTest('test_decorators.py', enabled=True, core=True), RegrTest('test_deque.py', enabled=True, core=True), - RegrTest('test_descr.py', enabled=False, core=True, oldstyle=True), - RegrTest('test_descrtut.py', enabled=False, core=True, oldstyle=True), + RegrTest('test_descr.py', enabled=True, core=True, oldstyle=True), + RegrTest('test_descrtut.py', enabled=True, core=True, oldstyle=True), RegrTest('test_dict.py', enabled=True, core=True), RegrTest('test_difflib.py', enabled=True, dumbtest=1), @@ -464,19 +458,18 @@ RegrTest('test_email_codecs.py', enabled=False, dumbtest=1), RegrTest('test_enumerate.py', enabled=True, core=True), - RegrTest('test_eof.py', enabled=False, core=True), - #rev 10840: some error strings differ slightly XXX + RegrTest('test_eof.py', enabled=True, core=True), RegrTest('test_errno.py', enabled=True, dumbtest=1), - RegrTest('test_exceptions.py', enabled=False, core=True), - RegrTest('test_extcall.py', enabled=False, core=True), + RegrTest('test_exceptions.py', enabled=True, core=True), + RegrTest('test_extcall.py', enabled=True, core=True), RegrTest('test_fcntl.py', enabled=False, dumbtest=1), - RegrTest('test_file.py', enabled=False, dumbtest=1, core=True, uselibfile=True), + RegrTest('test_file.py', enabled=True, dumbtest=1, core=True, uselibfile=True), RegrTest('test_filecmp.py', enabled=True, core=True), RegrTest('test_fileinput.py', enabled=True, dumbtest=1, core=True), RegrTest('test_fnmatch.py', enabled=True, core=True), RegrTest('test_fork1.py', enabled=False, dumbtest=1), - RegrTest('test_format.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_format.py', enabled=True, dumbtest=1, core=True), RegrTest('test_fpformat.py', enabled=True, core=True), RegrTest('test_frozen.py', enabled=False), RegrTest('test_funcattrs.py', enabled=True, dumbtest=1, core=True), @@ -484,9 +477,9 @@ RegrTest('test_future1.py', enabled=True, dumbtest=1, core=True), RegrTest('test_future2.py', enabled=True, dumbtest=1, core=True), RegrTest('test_future3.py', enabled=True, core=True), - RegrTest('test_gc.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_gc.py', enabled=True, dumbtest=1, core=True), RegrTest('test_gdbm.py', enabled=False, dumbtest=1), - RegrTest('test_generators.py', enabled=False, core=True), + RegrTest('test_generators.py', enabled=True, core=True), #rev 10840: 30 of 152 tests fail RegrTest('test_genexps.py', enabled=True, core=True), RegrTest('test_getargs.py', enabled=False, dumbtest=1), @@ -499,12 +492,12 @@ RegrTest('test_gl.py', enabled=False, dumbtest=1), RegrTest('test_glob.py', enabled=True, core=True), - RegrTest('test_global.py', enabled=False, core=True), + RegrTest('test_global.py', enabled=True, core=True), # this fails because it relies on the warnings module # turning a warning into an exception, but PyPy's # interplevel doesn't call into the app-level warnings # module - RegrTest('test_grammar.py', enabled=False, core=True), + RegrTest('test_grammar.py', enabled=True, core=True), RegrTest('test_grp.py', enabled=False), #rev 10840: ImportError: grp @@ -522,13 +515,13 @@ RegrTest('test_imageop.py', enabled=False, dumbtest=1), RegrTest('test_imaplib.py', enabled=True, dumbtest=1), RegrTest('test_imgfile.py', enabled=False, dumbtest=1), - RegrTest('test_imp.py', enabled=False, core="maybe"), - RegrTest('test_import.py', enabled=False, dumbtest=1, core="possibly"), - RegrTest('test_importhooks.py', enabled=False, core="possibly"), - RegrTest('test_inspect.py', enabled=False, dumbtest=1, core="maybe"), + RegrTest('test_imp.py', enabled=True, core=True), + RegrTest('test_import.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_importhooks.py', enabled=True, core=True), + RegrTest('test_inspect.py', enabled=True, dumbtest=1, core=True), RegrTest('test_ioctl.py', enabled=False), RegrTest('test_isinstance.py', enabled=True, core=True), - RegrTest('test_iter.py', enabled=False, core=True, uselibfile=True), + RegrTest('test_iter.py', enabled=True, core=True, uselibfile=True), #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser RegrTest('test_iterlen.py', enabled=True, core=True), RegrTest('test_itertools.py', enabled=True, core=True), @@ -540,14 +533,14 @@ RegrTest('test_locale.py', enabled=False, dumbtest=1), RegrTest('test_logging.py', enabled=False), RegrTest('test_long.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_long_future.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_long_future.py', enabled=True, dumbtest=1, core=True), RegrTest('test_longexp.py', enabled=True, core=True), RegrTest('test_macfs.py', enabled=False), RegrTest('test_macostools.py', enabled=False), RegrTest('test_macpath.py', enabled=True), RegrTest('test_mailbox.py', enabled=True), RegrTest('test_marshal.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_math.py', enabled=False, core=True, usemodules=['math']), + RegrTest('test_math.py', enabled=True, core=True, usemodules=['math']), RegrTest('test_md5.py', enabled=False), RegrTest('test_mhlib.py', enabled=True), RegrTest('test_mimetools.py', enabled=True), @@ -555,19 +548,19 @@ RegrTest('test_MimeWriter.py', enabled=True, core=True), RegrTest('test_minidom.py', enabled=False, dumbtest=1), RegrTest('test_mmap.py', enabled=False), - RegrTest('test_module.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_module.py', enabled=True, dumbtest=1, core=True), RegrTest('test_multibytecodec.py', enabled=True, core=True), RegrTest('test_multibytecodec_support.py', enabled=True, core=True), RegrTest('test_multifile.py', enabled=True), - RegrTest('test_mutants.py', enabled=False, dumbtest=1, core="possibly"), + RegrTest('test_mutants.py', enabled=True, dumbtest=1, core="possibly"), RegrTest('test_netrc.py', enabled=True), - RegrTest('test_new.py', enabled=False, core=True, oldstyle=True), + RegrTest('test_new.py', enabled=True, core=True, oldstyle=True), RegrTest('test_nis.py', enabled=False), RegrTest('test_normalization.py', enabled=False), RegrTest('test_ntpath.py', enabled=True, dumbtest=1), RegrTest('test_opcodes.py', enabled=True, core=True), RegrTest('test_openpty.py', enabled=False), - RegrTest('test_operations.py', enabled=False, core=True), + RegrTest('test_operations.py', enabled=True, core=True), RegrTest('test_operator.py', enabled=True, core=True), RegrTest('test_optparse.py', enabled=False), # this test fails because it expects that PyPy's builtin @@ -576,7 +569,7 @@ RegrTest('test_os.py', enabled=True, core=True), RegrTest('test_ossaudiodev.py', enabled=False), - RegrTest('test_parser.py', enabled=False, core=True), + RegrTest('test_parser.py', enabled=True, core=True), #rev 10840: 18 of 18 tests fail RegrTest('test_peepholer.py', enabled=True), @@ -587,9 +580,9 @@ # seems to be the only one that invokes run_unittest # and is an unittest RegrTest('test_pep292.py', enabled=True, core=True), - RegrTest('test_pickle.py', enabled=False, core=True), - RegrTest('test_pickletools.py', enabled=False, dumbtest=1, core=True), - RegrTest('test_pkg.py', enabled=False, core=True), + RegrTest('test_pickle.py', enabled=True, core=True), + RegrTest('test_pickletools.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_pkg.py', enabled=True, core=True), RegrTest('test_pkgimport.py', enabled=True, core=True), RegrTest('test_plistlib.py', enabled=False), RegrTest('test_poll.py', enabled=False), @@ -619,14 +612,14 @@ RegrTest('test_re.py', enabled=True, core=True), RegrTest('test_regex.py', enabled=False), - RegrTest('test_repr.py', enabled=False, core="ill-defined"), + RegrTest('test_repr.py', enabled=True, core="ill-defined"), #rev 10840: 6 of 12 tests fail. Always minor stuff like #'' != '' RegrTest('test_resource.py', enabled=False), RegrTest('test_rfc822.py', enabled=True), RegrTest('test_rgbimg.py', enabled=False), - RegrTest('test_richcmp.py', enabled=False, core=True), + RegrTest('test_richcmp.py', enabled=True, core=True), #rev 10840: 1 of 11 test fails. The failing one had an infinite recursion. RegrTest('test_robotparser.py', enabled=True), @@ -643,7 +636,7 @@ RegrTest('test_shlex.py', enabled=True), RegrTest('test_shutil.py', enabled=True), RegrTest('test_signal.py', enabled=False), - RegrTest('test_site.py', enabled=False, core=True), + RegrTest('test_site.py', enabled=True, core=True), # Needs non-faked codecs. RegrTest('test_slice.py', enabled=True, dumbtest=1, core=True), RegrTest('test_socket.py', enabled=False), @@ -654,8 +647,8 @@ #rev 10840: ImportError: thread RegrTest('test_softspace.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_sort.py', enabled=False, dumbtest=1, core=True), - RegrTest('test_str.py', enabled=False, core=True), + RegrTest('test_sort.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_str.py', enabled=True, core=True), #rev 10840: at least two tests fail, after several hours I gave up waiting for the rest RegrTest('test_strftime.py', enabled=False, dumbtest=1), @@ -686,14 +679,14 @@ #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser RegrTest('test_textwrap.py', enabled=True), - RegrTest('test_thread.py', enabled=False, core=True), - RegrTest('test_threaded_import.py', enabled=False, core=True), - RegrTest('test_threadedtempfile.py', enabled=False, core=True), + RegrTest('test_thread.py', enabled=True, core=True), + RegrTest('test_threaded_import.py', enabled=True, core=True), + RegrTest('test_threadedtempfile.py', enabled=True, core=True), #rev 10840: ImportError: thread - RegrTest('test_threading.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_threading.py', enabled=True, dumbtest=1, core=True), #rev 10840: ImportError: thread - RegrTest('test_threading_local.py', enabled=False, dumbtest=1, core=True), + RegrTest('test_threading_local.py', enabled=True, dumbtest=1, core=True), RegrTest('test_threadsignals.py', enabled=False, dumbtest=1), RegrTest('test_time.py', enabled=True, core=True), @@ -703,7 +696,7 @@ RegrTest('test_timing.py', enabled=False, dumbtest=1), RegrTest('test_tokenize.py', enabled=False), RegrTest('test_trace.py', enabled=True, core=True), - RegrTest('test_traceback.py', enabled=False, core=True), + RegrTest('test_traceback.py', enabled=True, core=True), #rev 10840: 2 of 2 tests fail RegrTest('test_transformer.py', enabled=True, core=True), RegrTest('test_tuple.py', enabled=True, core=True), @@ -715,7 +708,7 @@ RegrTest('test_ucn.py', enabled=False), RegrTest('test_unary.py', enabled=True, core=True), - RegrTest('test_unicode.py', enabled=False, core=True), + RegrTest('test_unicode.py', enabled=True, core=True), RegrTest('test_unicode_file.py', enabled=False), RegrTest('test_unicodedata.py', enabled=False), RegrTest('test_unittest.py', enabled=True, core=True), @@ -729,13 +722,13 @@ RegrTest('test_urlparse.py', enabled=True), RegrTest('test_userdict.py', enabled=True, core=True), RegrTest('test_userlist.py', enabled=True, core=True), - RegrTest('test_userstring.py', enabled=False, core=True), + RegrTest('test_userstring.py', enabled=True, core=True), RegrTest('test_uu.py', enabled=False), #rev 10840: 1 of 9 test fails RegrTest('test_warnings.py', enabled=True, core=True), RegrTest('test_wave.py', enabled=False, dumbtest=1), - RegrTest('test_weakref.py', enabled=False, core=True), + RegrTest('test_weakref.py', enabled=True, core=True), #rev 10840: ImportError: _weakref RegrTest('test_whichdb.py', enabled=True), @@ -748,7 +741,7 @@ RegrTest('test_xpickle.py', enabled=False), RegrTest('test_xrange.py', enabled=True, core=True), RegrTest('test_zipfile.py', enabled=False, dumbtest=1), - RegrTest('test_zipimport.py', enabled=False, core=True), + RegrTest('test_zipimport.py', enabled=True, core=True), #rev 10840: ImportError: zlib RegrTest('test_zlib.py', enabled=False), From nik at codespeak.net Tue Aug 23 16:38:49 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 16:38:49 +0200 (CEST) Subject: [pypy-svn] r16277 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050823143849.1098727B3D@code1.codespeak.net> Author: nik Date: Tue Aug 23 16:38:47 2005 New Revision: 16277 Added: pypy/dist/lib-python/modified-2.4.1/test/test_slice.py - copied, changed from r16260, pypy/dist/lib-python/2.4.1/test/test_slice.py Log: disabled tests for OverflowError. test_slice passes now. From ludal at codespeak.net Tue Aug 23 16:53:34 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 16:53:34 +0200 (CEST) Subject: [pypy-svn] r16279 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20050823145334.5EBAC27B41@code1.codespeak.net> Author: ludal Date: Tue Aug 23 16:53:32 2005 New Revision: 16279 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/astcompiler/symbols.py Log: - make astcompiler accept the new ast form for function arguments - some modifications make the compiler look more rpythonic - fixes to accept the new varname attribute for Name nodes Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Tue Aug 23 16:53:32 2005 @@ -5,7 +5,7 @@ import sys import types -from pypy.interpreter.astcompiler import misc +from pypy.interpreter.astcompiler import misc, ast from pypy.interpreter.astcompiler.consts \ import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS @@ -340,11 +340,16 @@ # The offsets used by LOAD_CLOSURE/LOAD_DEREF refer to both # kinds of variables. self.closure = [] - self.varnames = list(args) or [] - for i in range(len(self.varnames)): - var = self.varnames[i] - if isinstance(var, TupleArg): - self.varnames[i] = var.getName() + self.varnames = [] + for var in args: + if isinstance(var, ast.AssName): + self.varnames.append(var.name) + elif isinstance(var, TupleArg): + self.varnames.append(var.getName()) + elif isinstance(var, ast.AssTuple): + for n in var.flatten(): + assert isinstance(n, ast.AssName) + self.varnames.append(n.name) self.stage = RAW self.orderedblocks = [] @@ -397,6 +402,20 @@ if io: sys.stdout = save + def _max_depth(self, depth, seen, b, d): + if seen.has_key(b): + return d + seen[b] = 1 + d = d + depth[b] + children = b.get_children() + if children: + return max([ self._max_depth(depth, seen, c, d) for c in children]) + else: + if not b.label == "exit": + return self._max_depth(depth, seen, self.exit, d) + else: + return d + def computeStackDepth(self): """Compute the max stack depth. @@ -411,21 +430,7 @@ seen = {} - def max_depth(b, d): - if seen.has_key(b): - return d - seen[b] = 1 - d = d + depth[b] - children = b.get_children() - if children: - return max([max_depth(c, d) for c in children]) - else: - if not b.label == "exit": - return max_depth(self.exit, d) - else: - return d - - self.stacksize = max_depth(self.entry, 0) + self.stacksize = self._max_depth( depth, seen, self.entry, 0) def flattenGraph(self): """Arrange the blocks in order and resolve jumps""" @@ -661,7 +666,7 @@ if opname[:4] == 'JUMP': return 1 -class TupleArg: +class TupleArg(ast.Node): """Helper for marking func defs with nested tuples in arglist""" def __init__(self, count, names): self.count = count Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Aug 23 16:53:32 2005 @@ -14,12 +14,8 @@ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pypy.interpreter.astcompiler.pyassem import TupleArg -# XXX The version-specific code can go, since this code only works with 2.x. -# Do we have Python 1.x or Python 2.x? -try: - VERSION = sys.version_info[0] -except AttributeError: - VERSION = 1 +# drop VERSION dependency since it the ast transformer for 2.4 doesn't work with 2.3 anyway +VERSION = 2 callfunc_opcode_info = { # (Have *args, Have **args) : opcode @@ -186,12 +182,6 @@ This class is an abstract base class. Concrete subclasses must define an __init__() that defines self.graph and then calls the __init__() defined in this class. - - The concrete class must also define the class attributes - NameFinder, FunctionGen, and ClassGen. These attributes can be - defined in the initClass() method, which is a hook for - initializing these methods after all the classes have been - defined. """ optimized = 0 # is namespace access optimized? @@ -199,9 +189,6 @@ class_name = None # provide default for instance variable def __init__(self): - if self.__initialized is None: - self.initClass() - self.__class__.__initialized = 1 self.checkClass() self.locals = misc.Stack() self.setups = misc.Stack() @@ -218,9 +205,6 @@ elif feature == "generators": self.graph.setFlag(CO_GENERATOR_ALLOWED) - def initClass(self): - """This method is called once for each class""" - def checkClass(self): """Verify that class is constructed correctly""" try: @@ -848,8 +832,7 @@ def visitImport(self, node): self.set_lineno(node) for name, alias in node.names: - if VERSION > 1: - self.emit('LOAD_CONST', None) + self.emit('LOAD_CONST', None) self.emit('IMPORT_NAME', name) mod = name.split(".")[0] if alias: @@ -861,23 +844,19 @@ def visitFrom(self, node): self.set_lineno(node) fromlist = map(lambda (name, alias): name, node.names) - if VERSION > 1: - self.emit('LOAD_CONST', tuple(fromlist)) + self.emit('LOAD_CONST', tuple(fromlist)) self.emit('IMPORT_NAME', node.modname) for name, alias in node.names: - if VERSION > 1: - if name == '*': - self.namespace = 0 - self.emit('IMPORT_STAR') - # There can only be one name w/ from ... import * - assert len(node.names) == 1 - return - else: - self.emit('IMPORT_FROM', name) - self._resolveDots(name) - self.storeName(alias or name) + if name == '*': + self.namespace = 0 + self.emit('IMPORT_STAR') + # There can only be one name w/ from ... import * + assert len(node.names) == 1 + return else: self.emit('IMPORT_FROM', name) + self._resolveDots(name) + self.storeName(alias or name) self.emit('POP_TOP') def _resolveDots(self, name): @@ -1221,14 +1200,8 @@ self.emit('ROT_THREE') self.emit('STORE_SUBSCR') -class NestedScopeMixin: - """Defines initClass() for nested scoping (Python 2.2-compatible)""" - def initClass(self): - self.__class__.NameFinder = LocalNameFinder - self.__class__.FunctionGen = FunctionCodeGenerator - self.__class__.ClassGen = ClassCodeGenerator -class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator): +class ModuleCodeGenerator(CodeGenerator): __super_init = CodeGenerator.__init__ scopes = None @@ -1242,7 +1215,7 @@ def get_module(self): return self -class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator): +class ExpressionCodeGenerator(CodeGenerator): __super_init = CodeGenerator.__init__ scopes = None @@ -1256,7 +1229,7 @@ def get_module(self): return self -class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator): +class InteractiveCodeGenerator(CodeGenerator): __super_init = CodeGenerator.__init__ @@ -1324,24 +1297,27 @@ def generateArgUnpack(self, args): for i in range(len(args)): arg = args[i] - if type(arg) == types.TupleType: + if isinstance(arg, ast.AssTuple): self.emit('LOAD_FAST', '.%d' % (i * 2)) self.unpackSequence(arg) def unpackSequence(self, tup): if VERSION > 1: - self.emit('UNPACK_SEQUENCE', len(tup)) + self.emit('UNPACK_SEQUENCE', len(tup.nodes)) else: - self.emit('UNPACK_TUPLE', len(tup)) - for elt in tup: - if type(elt) == types.TupleType: - self.unpackSequence(elt) + self.emit('UNPACK_TUPLE', len(tup.nodes)) + + for elt in tup.nodes: + if isinstance(elt, ast.AssName): + self._nameOp('STORE', elt.name) + elif isinstance(elt, ast.AssTuple): + self.unpackSequence( elt ) else: - self._nameOp('STORE', elt) + raise TypeError( "Got argument %s of type %s" % (elt,type(elt))) unpackTuple = unpackSequence -class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode, +class FunctionCodeGenerator(AbstractFunctionCode, CodeGenerator): super_init = CodeGenerator.__init__ # call be other init scopes = None @@ -1357,7 +1333,7 @@ if self.scope.generator is not None: self.graph.setFlag(CO_GENERATOR) -class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode, +class GenExprCodeGenerator(AbstractFunctionCode, CodeGenerator): super_init = CodeGenerator.__init__ # call be other init scopes = None @@ -1394,7 +1370,7 @@ self.emit('LOAD_LOCALS') self.emit('RETURN_VALUE') -class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator): +class ClassCodeGenerator(AbstractClassCode, CodeGenerator): super_init = CodeGenerator.__init__ scopes = None @@ -1420,14 +1396,14 @@ count = 0 for i in range(len(arglist)): elt = arglist[i] - if type(elt) == types.StringType: + if isinstance(elt, ast.AssName): args.append(elt) - elif type(elt) == types.TupleType: + elif isinstance(elt, ast.AssTuple): args.append(TupleArg(i * 2, elt)) - extra.extend(misc.flatten(elt)) + extra.extend(ast.flatten(elt)) count = count + 1 else: - raise ValueError, "unexpect argument type:", elt + raise ValueError( "unexpect argument type: %s" % elt ) return args + extra, count def findOp(node): @@ -1486,6 +1462,15 @@ def wrap_aug(node): return wrapper[node.__class__](node) + +for klass in (ModuleCodeGenerator, ExpressionCodeGenerator, InteractiveCodeGenerator, + FunctionCodeGenerator, GenExprCodeGenerator, ClassCodeGenerator): + klass.NameFinder = LocalNameFinder + klass.FunctionGen = FunctionCodeGenerator + klass.ClassGen = ClassCodeGenerator + + + if __name__ == "__main__": for file in sys.argv[1:]: compileFile(file) Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Tue Aug 23 16:53:32 2005 @@ -281,11 +281,13 @@ self.handle_free_vars(scope, parent) def _do_args(self, scope, args): - for name in args: - if type(name) == types.TupleType: - self._do_args(scope, name) + for arg in args: + if isinstance( arg, ast.AssName ): + scope.add_param( arg.name ) + elif isinstance( arg, ast.AssTuple ): + self._do_args( scope, arg.flatten() ) else: - scope.add_param(name) + raise TypeError( "Argument list contains %s of type %s" % (arg, type(arg) ) ) def handle_free_vars(self, scope, parent): parent.add_child(scope) @@ -316,9 +318,9 @@ def visitName(self, node, scope, assign=0): if assign: - scope.add_def(node.name) + scope.add_def(node.varname) else: - scope.add_use(node.name) + scope.add_use(node.varname) # operations that bind new names From ludal at codespeak.net Tue Aug 23 16:55:01 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 16:55:01 +0200 (CEST) Subject: [pypy-svn] r16280 - in pypy/dist/pypy: interpreter/pyparser translator/goal Message-ID: <20050823145501.9B25927B41@code1.codespeak.net> Author: ludal Date: Tue Aug 23 16:55:00 2005 New Revision: 16280 Added: pypy/dist/pypy/translator/goal/targetcompiler.py Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py Log: a new target to try and translate the whole compiler Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Tue Aug 23 16:55:00 2005 @@ -107,6 +107,14 @@ PYTHON_PARSER.parse_source(input, target, builder) return builder.rule_stack[-1] +def ast_compile(input, mode): + from pypy.interpreter.astcompiler import ast, misc, pycodegen + ast_tree = ast_from_input_( input, mode ) + misc.set_filename("", ast_tree) + codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) + code1 = codegenerator.getCode() + return code1 + def internal_pypy_parse_to_ast(source, mode='exec', lineno=False, flags=0): builder = AstBuilder() Added: pypy/dist/pypy/translator/goal/targetcompiler.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/targetcompiler.py Tue Aug 23 16:55:00 2005 @@ -0,0 +1,24 @@ +import os, sys +from pypy.annotation.model import * +from pypy.annotation.listdef import ListDef + +# WARNING: this requires the annotator. +# There is no easy way to build all caches manually, +# but the annotator can do it for us for free. + +this_dir = os.path.dirname(sys.argv[0]) + +# from pypy.interpreter.pyparser.pythonutil import annotateme +# __________ Entry point __________ +# entry_point = annotateme + +from pypy.interpreter.pyparser.pythonutil import ast_compile +entry_point = ast_compile + +# _____ Define and setup target ___ +def target(): + return entry_point, [str, str] + +# _____ Run translated _____ +def run(c_entry_point): + pass From tismer at codespeak.net Tue Aug 23 16:57:13 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 16:57:13 +0200 (CEST) Subject: [pypy-svn] r16281 - pypy/dist/pypy/interpreter Message-ID: <20050823145713.6333727B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 16:57:12 2005 New Revision: 16281 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: needed to move the applevel stuff into the __init__ context. Otherwise, the annotator would complain. Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 16:57:12 2005 @@ -240,26 +240,29 @@ PythonCompiler.__init__(self, space) debug_print("importing the 'compiler' package at app-level...", newline=False) - self._load_compiler('single') + self._load_compilers() debug_print(" done") - def _load_compiler(self, mode): - if mode == 'single': - self.w_applevelcompile = self.space.appexec([], r'''(): - from _stablecompiler import apphook + def _load_compilers(self): + comp1 = self.space.appexec([], r'''(): + from _stablecompiler import apphook + return apphook.applevelcompile + ''') + comp2 = self.w_applevelcompile = self.space.appexec([], r'''(): + import os + from _stablecompiler import apphook + if os.path.exists('fakecompiler.py'): + print "faking compiler, because fakecompiler.py is in the current dir" + import fakecompiler + return fakecompiler.fakeapplevelcompile + else: return apphook.applevelcompile - ''') - else: - self.w_applevelcompile = self.space.appexec([], r'''(): - import os - from _stablecompiler import apphook - if os.path.exists('fakecompiler.py'): - print "faking compiler, because fakecompiler.py is in the current dir" - import fakecompiler - return fakecompiler.fakeapplevelcompile - else: - return apphook.applevelcompile - ''') + ''') + self.applevelcompile_w = { + 'single': compile1, + 'eval': compile2, + 'exec': compile2, + } def compile_parse_result(self, parse_result, filename, mode): space = self.space @@ -279,8 +282,7 @@ w_nested_tuples, space.wrap(source_encoding)]) - self._load_compiler(mode) - w_code = space.call_function(self.w_applevelcompile, + w_code = space.call_function(self.applevelcompile_w[mode], w_nested_tuples, space.wrap(filename), space.wrap(mode)) From ludal at codespeak.net Tue Aug 23 16:58:33 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 16:58:33 +0200 (CEST) Subject: [pypy-svn] r16282 - pypy/dist/pypy/interpreter Message-ID: <20050823145833.B041427B41@code1.codespeak.net> Author: ludal Date: Tue Aug 23 16:58:32 2005 New Revision: 16282 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: trying to translate PythonAstCompiler Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 16:58:32 2005 @@ -325,7 +325,7 @@ from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator space = self.space try: - astcompiler.misc.set_filename(filename, ast_tree) ### TODO: doesn't work + astcompiler.misc.set_filename(filename, ast_tree) if mode == 'exec': codegenerator = ModuleCodeGenerator(ast_tree) elif mode == 'single': @@ -348,7 +348,7 @@ # __________ end of XXX above from pypy.interpreter.pycode import PyCode return PyCode(space)._from_code(c) - compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' + #compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' From ludal at codespeak.net Tue Aug 23 17:00:18 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 17:00:18 +0200 (CEST) Subject: [pypy-svn] r16283 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20050823150018.3A5E127B41@code1.codespeak.net> Author: ludal Date: Tue Aug 23 17:00:15 2005 New Revision: 16283 Added: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Log: removed non rpython version of parse_fpdef update tests accordingly added some tests for compilation Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Tue Aug 23 17:00:15 2005 @@ -97,96 +97,32 @@ return arguments, stararg_token, dstararg_token -class BaseItem: - """base item class""" - -class SimpleItem(BaseItem): - def __init__(self, attrname): - self.attrname = attrname - -class TupleItem(BaseItem): - def __init__(self, value): - self.value = value - - def append(self, element): - assert isinstance(element, BaseItem) - self.value.append(element) - - def pop(self): - return self.value.pop() - -def rpython_parse_fpdef(tokens): +def parse_fpdef(tokens): """fpdef: fpdef: NAME | '(' fplist ')' fplist: fpdef (',' fpdef)* [','] This intend to be a RPYTHON compliant implementation of _parse_fpdef, but it can't work with the default compiler. - XXX: incomplete + We switched to use astcompiler module now """ - stack = [] # list of lists + top = ast.AssTuple([]) + stack = [ top ] tokens_read = 0 - to_be_closed = 1 # number of parenthesis to be closed - result = None - while to_be_closed > 0: + while stack: token = tokens[tokens_read] tokens_read += 1 if isinstance(token, TokenObject) and token.name == tok.COMMA: continue elif isinstance(token, TokenObject) and token.name == tok.LPAR: - stack.append(TupleItem([])) - to_be_closed += 1 + new_tuple = ast.AssTuple([]) + stack[-1].nodes.append( new_tuple ) + stack.append(new_tuple) elif isinstance(token, TokenObject) and token.name == tok.RPAR: - to_be_closed -= 1 - elt = stack.pop() - if to_be_closed > 0: - top = stack[-1] - assert isinstance(top, TupleItem) - top.append(elt) - else: - # stack.append(tuple(elt)) - break + stack.pop() else: assert isinstance(token, TokenObject) - if to_be_closed == 1: - stack.append(SimpleItem(token.get_value())) - else: - top = stack[-1] - assert isinstance(top, TupleItem) - top.append(SimpleItem(token.get_value())) - return tokens_read, stack - -def working_parse_fpdef(tokens): - """fpdef: fpdef: NAME | '(' fplist ')' - fplist: fpdef (',' fpdef)* [','] - """ - # FIXME: will we need to implement a Stack class to be RPYTHON compliant ? - stack = [[],] # list of lists - tokens_read = 0 - to_be_closed = 1 # number of parenthesis to be closed - result = None - while to_be_closed > 0: - token = tokens[tokens_read] - tokens_read += 1 - if isinstance(token, TokenObject) and token.name == tok.COMMA: - continue - elif isinstance(token, TokenObject) and token.name == tok.LPAR: - stack.append([]) - to_be_closed += 1 - elif isinstance(token, TokenObject) and token.name == tok.RPAR: - to_be_closed -= 1 - elt = stack.pop() - if to_be_closed > 0: - stack[-1].append(tuple(elt)) - else: - stack.append(tuple(elt)) - else: - assert isinstance(token, TokenObject) - stack[-1].append(token.get_value()) - assert len(stack) == 1, "At the end of parse_fpdef, len(stack) should be 1, got %s" % stack - return tokens_read, tuple(stack[0]) - -# parse_fpdef = rpython_parse_fpdef -parse_fpdef = working_parse_fpdef + stack[-1].nodes.append(ast.AssName(token.get_value(),consts.OP_ASSIGN)) + return tokens_read, top def parse_arglist(tokens): """returns names, defaults, flags""" @@ -206,16 +142,16 @@ # but we might do some experiment on the grammar at some point continue elif cur_token.name == tok.LPAR: - tokens_read, name = parse_fpdef(tokens[index:]) + tokens_read, name_tuple = parse_fpdef(tokens[index:]) index += tokens_read - names.append(name) + names.append(name_tuple) elif cur_token.name == tok.STAR or cur_token.name == tok.DOUBLESTAR: if cur_token.name == tok.STAR: cur_token = tokens[index] assert isinstance(cur_token, TokenObject) index += 1 if cur_token.name == tok.NAME: - names.append(cur_token.get_value()) + names.append( ast.AssName( cur_token.get_value(), consts.OP_ASSIGN ) ) flags |= consts.CO_VARARGS index += 1 if index >= l: @@ -232,7 +168,7 @@ index += 1 assert isinstance(cur_token, TokenObject) if cur_token.name == tok.NAME: - names.append(cur_token.get_value()) + names.append( ast.AssName( cur_token.get_value(), consts.OP_ASSIGN ) ) flags |= consts.CO_VARKEYWORDS index += 1 else: @@ -240,7 +176,7 @@ if index < l: raise ValueError("unexpected token: %s" % tokens[index]) elif cur_token.name == tok.NAME: - names.append(cur_token.get_value()) + names.append( ast.AssName( cur_token.get_value(), consts.OP_ASSIGN ) ) return names, defaults, flags @@ -410,10 +346,11 @@ eval_number intends to replace number = eval(value) ; return number """ from pypy.objspace.std.strutil import string_to_int, string_to_float + from pypy.objspace.std.strutil import string_to_long from pypy.objspace.std.strutil import ParseStringError if value.endswith('l') or value.endswith('L'): value = value[:-1] - return string_to_long(value) # ??? + # ??? try: return string_to_int(value) except ParseStringError: Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Tue Aug 23 17:00:15 2005 @@ -12,12 +12,52 @@ from pypy.interpreter.astcompiler import ast +def arglist_equal(left,right): + """needs special case because we handle the argumentlist differently""" + for l,r in zip(left,right): + if type(l)==str and isinstance(r,ast_ast.AssName): + if l!=r.name: + print "Name mismatch", l, r.name + return False + elif type(l)==tuple and isinstance(r,ast_ast.AssTuple): + if not arglist_equal(l,r.nodes): + print "Tuple mismatch" + return False + else: + print "Type mismatch", repr(l), repr(r) + print "l is str", type(l)==str + print "r is AssName", isinstance(r,ast_ast.AssName) + return False + return True + + def nodes_equal(left, right): if type(left)!=type(right): return False if not isinstance(left,stable_ast.Node) or not isinstance(right,ast_ast.Node): return left==right - for i,j in zip(left.getChildren(),right.getChildren()): + if isinstance(left,stable_ast.Function) and isinstance(right,ast_ast.Function): + left_nodes = list(left.getChildren()) + right_nodes = list(right.getChildren()) + left_args = left_nodes[2] + del left_nodes[2] + right_args = right_nodes[2] + del right_nodes[2] + if not arglist_equal(left_args, right_args): + return False + elif isinstance(left,stable_ast.Lambda) and isinstance(right,ast_ast.Lambda): + left_nodes = list(left.getChildren()) + right_nodes = list(right.getChildren()) + left_args = left_nodes[0] + del left_nodes[0] + right_args = right_nodes[0] + del right_nodes[0] + if not arglist_equal(left_args, right_args): + return False + else: + left_nodes = left.getChildren() + right_nodes = right.getChildren() + for i,j in zip(left_nodes,right_nodes): if not nodes_equal(i,j): return False return True Added: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Tue Aug 23 17:00:15 2005 @@ -0,0 +1,66 @@ +from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER +from pypy.interpreter.pyparser.astbuilder import AstBuilder + + +from pypy.interpreter.pyparser.pythonutil import ast_from_input +import py.test + +from pypy.interpreter.astcompiler import ast, misc, pycodegen + + +TARGET_DICT = { + 'single' : 'single_input', + 'exec' : 'file_input', + 'eval' : 'eval_input', + } + +def ast_parse_expr(expr, target='single'): + target = TARGET_DICT[target] + builder = AstBuilder() + PYTHON_PARSER.parse_source(expr, target, builder) + return builder.rule_stack[-1] + + +### Note: builtin compile and compiler.compile behave differently +def compile_expr( expr, target="single" ): + return compile( expr, "", target ) + +def ast_compile( expr, target="single" ): + from compiler import compile + return compile( expr, "", target ) + + +def compare_code( code1, code2 ): + print "Filename", code1.co_filename, code2.co_filename + assert code1.co_filename == code2.co_filename + print repr(code1.co_code) + print repr(code2.co_code) + assert code1.co_code == code2.co_code + +def check_compile( expr ): + ast_tree = ast_parse_expr( expr ) + misc.set_filename("", ast_tree) + print ast_tree + codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) + code1 = codegenerator.getCode() + code2 = ast_compile( expr ) + compare_code(code1,code2) + +def test_compile_argtuple_1(): + code = """def f( x, (y,z) ): + print x,y,z +""" + check_compile( code ) + +def test_compile_argtuple_2(): + code = """def f( x, (y,(z,t)) ): + print x,y,z,t +""" + check_compile( code ) + + +def test_compile_argtuple_3(): + code = """def f( x, (y,(z,(t,u))) ): + print x,y,z,t,u +""" + check_compile( code ) Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_samples.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Tue Aug 23 17:00:15 2005 @@ -19,6 +19,7 @@ SKIP_IF_NOT_NATIVE = [ #"snippet_samples.py", #"snippet_import_statements.py", + "snippet_decorators.py", ] From tismer at codespeak.net Tue Aug 23 17:00:32 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 17:00:32 +0200 (CEST) Subject: [pypy-svn] r16284 - pypy/dist/pypy/interpreter Message-ID: <20050823150032.65D2E27B47@code1.codespeak.net> Author: tismer Date: Tue Aug 23 17:00:31 2005 New Revision: 16284 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: ouuupps Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 17:00:31 2005 @@ -244,11 +244,11 @@ debug_print(" done") def _load_compilers(self): - comp1 = self.space.appexec([], r'''(): + compile1 = self.space.appexec([], r'''(): from _stablecompiler import apphook return apphook.applevelcompile ''') - comp2 = self.w_applevelcompile = self.space.appexec([], r'''(): + compile2 = self.w_applevelcompile = self.space.appexec([], r'''(): import os from _stablecompiler import apphook if os.path.exists('fakecompiler.py'): From pedronis at codespeak.net Tue Aug 23 17:04:14 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 23 Aug 2005 17:04:14 +0200 (CEST) Subject: [pypy-svn] r16285 - pypy/dist/pypy/translator/c Message-ID: <20050823150414.CC57527B41@code1.codespeak.net> Author: pedronis Date: Tue Aug 23 17:04:13 2005 New Revision: 16285 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/node.py Log: started factoring refcounting logic from node.py into RefcountingPolicy (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Aug 23 17:04:13 2005 @@ -74,8 +74,8 @@ argtypes = ', '.join(argtypes) or 'void' return resulttype.replace('@', '(@)(%s)' % argtypes) elif isinstance(T, OpaqueType): - if T == RuntimeTypeInfo: # xxx -> gc - return 'void (@)(void *)' # void dealloc_xx(struct xx *) + if T == RuntimeTypeInfo: + return self.gcpolicy.rtti_type() elif hasattr(T, '_exttypeinfo'): # for external types (pypy.rpython.extfunctable.declaretype()) node = self.gettypedefnode(T, varlength=varlength) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Aug 23 17:04:13 2005 @@ -1,5 +1,6 @@ from pypy.translator.c.support import cdecl -from pypy.rpython.lltype import Ptr, PyObject +from pypy.rpython.lltype import typeOf, Ptr, PyObject +from pypy.rpython.lltype import getRuntimeTypeInfo PyObjPtr = Ptr(PyObject) @@ -34,6 +35,9 @@ return self.pop_alive_nopyobj(expr, T) return '' +class RefcountingInfo: + deallocator = None + static_deallocator = None class RefcountingGcPolicy(BasicGcPolicy): @@ -71,3 +75,80 @@ result.append('}') + def rtti_type(self): + return 'void (@)(void *)' # void dealloc_xx(struct xx *) + + def gcheader_field_name(self, defnode): + return 'refcount' + + def common_gcheader_definition(self, defnode): + yield 'long refcount;' + + def common_after_definition(self, defnode): + if defnode.gcinfo: + gcinfo = defnode.gcinfo + if gcinfo.deallocator: + yield 'void %s(struct %s *);' % (gcinfo.deallocator, defnode.name) + + def common_gcheader_initializationexpr(self, defnode): + yield 'REFCOUNT_IMMORTAL,' + + # for structs + + def prepare_nested_gcstruct(self, structdefnode, INNER): + # check here that there is enough run-time type information to + # handle this case + getRuntimeTypeInfo(structdefnode.STRUCT) + getRuntimeTypeInfo(INNER) + + def struct_setup(self, structdefnode, rtti): + if structdefnode.gcheader: + db = self.db + gcinfo = structdefnode.gcinfo = RefcountingInfo() + + gcinfo.deallocator = db.namespace.uniquename('dealloc_'+structdefnode.barename) + + # are two deallocators needed (a dynamic one for DECREF, which checks + # the real type of the structure and calls the static deallocator) ? + if rtti is not None: + gcinfo.static_deallocator = db.namespace.uniquename( + 'staticdealloc_'+structdefnode.barename) + fnptr = rtti._obj.query_funcptr + if fnptr is None: + raise NotImplementedError( + "attachRuntimeTypeInfo(): please provide a function") + gcinfo.rtti_query_funcptr = db.get(fnptr) + T = typeOf(fnptr).TO.ARGS[0] + gcinfo.rtti_query_funcptr_argtype = db.gettype(T) + else: + # is a deallocator really needed, or would it be empty? + if list(structdefnode.deallocator_lines('')): + gcinfo.static_deallocator = gcinfo.deallocator + else: + gcinfo.deallocator = None + + struct_gcheader_definition = common_gcheader_definition + + struct_after_definition = common_after_definition + + def struct_implentationcode(self, structdefnode): + pass + + struct_gcheader_initialitionexpr = common_gcheader_initializationexpr + + # for arrays + + def array_setup(self, arraydefnode): + if arraydefnode.gcheader and list(arraydefnode.deallocator_lines('')): + gcinfo = arraydefnode.gcinfo = RefcountingInfo() + gcinfo.deallocator = self.db.namespace.uniquename('dealloc_'+arraydefnode.barename) + + array_gcheader_definition = common_gcheader_definition + + array_after_definition = common_after_definition + + def array_implementationcode(self, arraydefnode): + pass + + array_gcheader_initialitionexpr = common_gcheader_initializationexpr + Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Aug 23 17:04:13 2005 @@ -20,11 +20,6 @@ return False # gcheader already in the first field return True -class GcInfo: - deallocator = None - static_deallocator = None - - class StructDefNode: gcheader = None @@ -51,9 +46,11 @@ self.dependencies = {} self.prefix = somelettersfrom(STRUCT._name) + '_' + gcpolicy = db.gcpolicy + # look up the gcheader field if needs_gcheader(STRUCT): - self.gcheader = 'refcount' + self.gcheader = gcpolicy.gcheader_field_name(self) elif isinstance(STRUCT, GcStruct): # gcheader in the first field T = self.c_struct_field_type(STRUCT._names[0]) @@ -61,11 +58,10 @@ firstdefnode = db.gettypedefnode(T) firstfieldname = self.c_struct_field_name(STRUCT._names[0]) self.gcheader = '%s.%s' % (firstfieldname, firstdefnode.gcheader) - # check here that there is enough run-time type information to - # handle this case - # xxx -> gc hook - getRuntimeTypeInfo(STRUCT) - getRuntimeTypeInfo(T) + + # give the gcpolicy a chance to do sanity checking or special preparation for + # this case + gcpolicy.prepare_nested_gcstruct(self, T) def setup(self): # this computes self.fields @@ -91,29 +87,7 @@ # do we need deallocator(s)? if varlength == 1: - if self.gcheader: # xxx -> gc - gcinfo = self.gcinfo = GcInfo() - - gcinfo.deallocator = db.namespace.uniquename('dealloc_'+self.barename) - - # are two deallocators needed (a dynamic one for DECREF, which checks - # the real type of the structure and calls the static deallocator) ? - if rtti is not None: - gcinfo.static_deallocator = db.namespace.uniquename( - 'staticdealloc_'+self.barename) - fnptr = rtti._obj.query_funcptr - if fnptr is None: - raise NotImplementedError( - "attachRuntimeTypeInfo(): please provide a function") - gcinfo.rtti_query_funcptr = db.get(fnptr) - T = typeOf(fnptr).TO.ARGS[0] - gcinfo.rtti_query_funcptr_argtype = db.gettype(T) - else: - # is a deallocator really needed, or would it be empty? - if list(self.deallocator_lines('')): - gcinfo.static_deallocator = gcinfo.deallocator - else: - gcinfo.deallocator = None + self.db.gcpolicy.struct_setup(self, rtti) def c_struct_field_name(self, name): return self.prefix + name @@ -126,20 +100,23 @@ return '%s.%s' % (baseexpr, fldname) def definition(self, phase): + gcpolicy = self.db.gcpolicy if phase == 1: yield 'struct %s {' % self.name - if needs_gcheader(self.STRUCT): # xxx -> gc - yield '\tlong refcount;' + # gcheader + if needs_gcheader(self.STRUCT): + for line in gcpolicy.struct_gcheader_definition(self): + yield '\t' + line + for name, typename in self.fields: line = '%s;' % cdecl(typename, name) if typename == PrimitiveType[Void]: line = '/* %s */' % line yield '\t' + line yield '};' - if self.gcinfo: # xxx -> gc - gcinfo = self.gcinfo - if gcinfo.deallocator: - yield 'void %s(struct %s *);' % (gcinfo.deallocator, self.name) + + for line in gcpolicy.struct_after_definition(self): + yield line elif phase == 2: # xxx -> gc if self.gcinfo: @@ -210,10 +187,10 @@ bare=True) self.dependencies = {} - # look up the reference counter field + # look up the gcheader field name if needs_gcheader(ARRAY): - self.gcheader = 'refcount' # xxx -> gc - + self.gcheader = self.db.gcpolicy.gcheader_field_name(self) + def setup(self): db = self.db ARRAY = self.ARRAY @@ -222,28 +199,28 @@ # is a specific deallocator needed? if varlength == 1: - if self.gcheader and list(self.deallocator_lines('')): - gcinfo = self.gcinfo = GcInfo() - gcinfo.deallocator = db.namespace.uniquename('dealloc_'+self.barename) + self.db.gcpolicy.array_setup(self) def access_expr(self, baseexpr, index): return '%s.items[%d]' % (baseexpr, index) def definition(self, phase): + gcpolicy = self.db.gcpolicy if phase == 1: yield 'struct %s {' % self.name + # gcheader if needs_gcheader(self.ARRAY): - yield '\tlong refcount;' # xxx -> gc + for line in gcpolicy.array_gcheader_definition(self): + yield '\t' + line yield '\tlong length;' line = '%s;' % cdecl(self.itemtypename, 'items[%d]'% self.varlength) if self.ARRAY.OF == Void: # strange line = '/* %s */' % line yield '\t' + line yield '};' - if self.gcinfo: # xxx -> gc - gcinfo = self.gcinfo - if gcinfo.deallocator: - yield 'void %s(struct %s *a);' % (gcinfo.deallocator, self.name) + + for line in gcpolicy.array_after_definition(self): + yield line elif phase == 2: if self.gcinfo: # xxx -> gc @@ -390,8 +367,9 @@ def initializationexpr(self, decoration=''): yield '{' - if needs_gcheader(self.T): # xxx -> gc - yield '\tREFCOUNT_IMMORTAL,' + if needs_gcheader(self.T): + for line in self.db.gcpolicy.struct_gcheader_initialitionexpr(self): + yield '\t' + line defnode = self.db.gettypedefnode(self.T) for name in self.T._names: value = getattr(self.obj, name) @@ -419,8 +397,9 @@ def initializationexpr(self, decoration=''): yield '{' - if needs_gcheader(self.T): # xxx -> gc - yield '\tREFCOUNT_IMMORTAL,' + if needs_gcheader(self.T): + for line in self.db.gcpolicy.array_gcheader_initialitionexpr(self): + yield '\t' + line if self.T.OF == Void or len(self.obj.items) == 0: yield '\t%d' % len(self.obj.items) yield '}' From hpk at codespeak.net Tue Aug 23 17:06:14 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 17:06:14 +0200 (CEST) Subject: [pypy-svn] r16286 - pypy/dist/pypy/tool/pytest Message-ID: <20050823150614.6275827B41@code1.codespeak.net> Author: hpk Date: Tue Aug 23 17:06:13 2005 New Revision: 16286 Modified: pypy/dist/pypy/tool/pytest/htmlreport.py Log: more explicit information regarding the test results Modified: pypy/dist/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/htmlreport.py (original) +++ pypy/dist/pypy/tool/pytest/htmlreport.py Tue Aug 23 17:06:13 2005 @@ -107,21 +107,28 @@ body.append(html.h2("PyPy - latest compliance test results - " "core tests")) - ok = len([x for x in coretests if x.isok()]) - err = len([x for x in coretests if x.iserror()]) - to = len([x for x in coretests if x.istimeout()]) - sum = ok + err + to - sum100 = sum / 100.0 - body.append(html.div( "%.2f%% passed, %.2f%% timeout, %.2f%% ERROR" % ( - ok/sum100, to/sum100, err/sum100), - style="font-weight: bold")) + body.append(self.render_test_summary(coretests)) body.append(self.render_latest_table(coretests)) - body.append( html.h2("PyPy - latest compliance test results - non-core tests")) + body.append(self.render_test_summary(noncoretests)) body.append(self.render_latest_table(noncoretests)) doc.writetopath(indexpath) + def render_test_summary(self, tests): + ok = len([x for x in tests if x.isok()]) + err = len([x for x in tests if x.iserror()]) + to = len([x for x in tests if x.istimeout()]) + sum = ok + err + to + sum100 = sum / 100.0 + t = html.table() + def row(*args): + return html.tr(*[html.td(arg) for arg in args]) + t.append(row("testmodules passed completely", "%.2f%%" % (ok/sum100))) + t.append(row("testmodules (partially) failed", "%.2f%%" % (err/sum100))) + t.append(row("testmodules timeout", "%.2f%%" % (to/sum100))) + return t + class Document(object): def __init__(self, title=None): self.body = html.body() From ale at codespeak.net Tue Aug 23 17:06:52 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 17:06:52 +0200 (CEST) Subject: [pypy-svn] r16287 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050823150652.F023527B41@code1.codespeak.net> Author: ale Date: Tue Aug 23 17:06:51 2005 New Revision: 16287 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_enumerate.py Log: commented a test of implementation detail out Modified: pypy/dist/lib-python/modified-2.4.1/test/test_enumerate.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_enumerate.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_enumerate.py Tue Aug 23 17:06:51 2005 @@ -141,9 +141,10 @@ self.assertEqual(list(data)[::-1], list(reversed(data))) self.assertRaises(TypeError, reversed, {}) - def test_xrange_optimization(self): - x = xrange(1) - self.assertEqual(type(reversed(x)), type(iter(x))) +# Implementation detail +# def test_xrange_optimization(self): +# x = xrange(1) +# self.assertEqual(type(reversed(x)), type(iter(x))) def test_len(self): # This is an implementation detail, not an interface requirement From ale at codespeak.net Tue Aug 23 17:09:43 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 17:09:43 +0200 (CEST) Subject: [pypy-svn] r16288 - pypy/dist/pypy/module/__builtin__ Message-ID: <20050823150943.6AAC327B41@code1.codespeak.net> Author: ale Date: Tue Aug 23 17:09:40 2005 New Revision: 16288 Modified: pypy/dist/pypy/module/__builtin__/app_functional.py Log: make sure to exhaust reverse iterator if the underlying sequence shrinks to less than the remaining items Modified: pypy/dist/pypy/module/__builtin__/app_functional.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_functional.py (original) +++ pypy/dist/pypy/module/__builtin__/app_functional.py Tue Aug 23 17:09:40 2005 @@ -362,6 +362,8 @@ return self def next(self): + if self.remaining > len(self.seq): + self.remaining = 0 i = self.remaining if i > 0: i -= 1 @@ -371,4 +373,6 @@ raise StopIteration def __len__(self): + if self.remaining > len(self.seq): + self.remaining = 0 return self.remaining From nik at codespeak.net Tue Aug 23 17:16:28 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 17:16:28 +0200 (CEST) Subject: [pypy-svn] r16289 - pypy/dist/pypy/module/_sre Message-ID: <20050823151628.F2BDB27B41@code1.codespeak.net> Author: nik Date: Tue Aug 23 17:16:27 2005 New Revision: 16289 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: one more fix. this version now annotates fine. still needs to be tested on a full translation. Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Tue Aug 23 17:16:27 2005 @@ -4,6 +4,9 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.gateway import interp2app +import sys +BIG_ENDIAN = sys.byteorder == "big" + #### Exposed functions # XXX can we import those safely from sre_constants? @@ -324,7 +327,6 @@ return space.newbool(False) function = set_dispatch_table[opcode] result = function(space, context, char_code) - print result return space.newbool(result == MatchContext.OK) def set_failure(space, ctx, char_code): @@ -401,12 +403,11 @@ def to_byte_array(int_value): """Creates a list of bytes out of an integer representing data that is CODESIZE bytes wide.""" - import sys byte_array = [0] * CODESIZE for i in range(CODESIZE): byte_array[i] = int_value & 0xff int_value = int_value >> 8 - if sys.byteorder == "big": + if BIG_ENDIAN: # Uhm, maybe there's a better way to reverse lists byte_array_reversed = [0] * CODESIZE for i in range(CODESIZE): From ale at codespeak.net Tue Aug 23 17:18:06 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 17:18:06 +0200 (CEST) Subject: [pypy-svn] r16290 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050823151806.C1B5527B41@code1.codespeak.net> Author: ale Date: Tue Aug 23 17:18:05 2005 New Revision: 16290 Modified: pypy/dist/pypy/objspace/std/iterobject.py pypy/dist/pypy/objspace/std/itertype.py pypy/dist/pypy/objspace/std/test/test_iterobject.py Log: Added a reverse sequence iterator make sure to exhaust reverse iterator if the underlying sequence shrinks to less than the remaining items Modified: pypy/dist/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/iterobject.py (original) +++ pypy/dist/pypy/objspace/std/iterobject.py Tue Aug 23 17:18:05 2005 @@ -9,18 +9,27 @@ class W_SeqIterObject(W_Object): from pypy.objspace.std.itertype import iter_typedef as typedef - direction = +1 def __init__(w_self, space, w_seq, index=0): W_Object.__init__(w_self, space) w_self.w_seq = w_seq w_self.index = index -class W_ReverseSeqIterObject(W_SeqIterObject): - direction = -1 +class W_ReverseSeqIterObject(W_Object): + from pypy.objspace.std.itertype import reverse_iter_typedef as typedef + + def __init__(w_self, space, w_seq, index=-1): + W_Object.__init__(w_self, space) + w_self.w_seq = w_seq + w_self.w_len = space.len(w_seq) + if index < 0: + w_self.index = space.unwrap(w_self.w_len) + index + else: + w_self.index = space.unwrap(w_self.w_len) -registerimplementation(W_SeqIterObject) +registerimplementation(W_SeqIterObject) +registerimplementation(W_ReverseSeqIterObject) def iter__SeqIter(space, w_seqiter): return w_seqiter @@ -35,16 +44,48 @@ if not e.match(space, space.w_IndexError): raise raise OperationError(space.w_StopIteration, space.w_None) - w_seqiter.index += w_seqiter.direction + w_seqiter.index += 1 return w_item def len__SeqIter(space, w_seqiter): if w_seqiter.w_seq is None: return space.wrap(0) index = w_seqiter.index - if w_seqiter.direction == -1: - index = ~index # -1=>0, -2=>1, etc. - w_len = space.sub(space.len(w_seqiter.w_seq), space.wrap(index)) + w_length = space.len(w_seqiter.w_seq) + w_len = space.sub(w_length, space.wrap(index)) + if space.is_true(space.lt(w_len,space.wrap(0))): + w_len = space.wrap(0) + return w_len + +def iter__ReverseSeqIter(space, w_seqiter): + return w_seqiter + +def next__ReverseSeqIter(space, w_seqiter): + if w_seqiter.w_seq is None or w_seqiter.index < 0: + raise OperationError(space.w_StopIteration, space.w_None) + try: + w_item = space.getitem(w_seqiter.w_seq, space.wrap(w_seqiter.index)) + w_seqiter.index -= 1 + except OperationError, e: + w_seqiter.w_seq = None + if not e.match(space, space.w_IndexError): + raise + raise OperationError(space.w_StopIteration, space.w_None) + return w_item + +def len__ReverseSeqIter(space, w_seqiter): + if w_seqiter.w_seq is None: + return space.wrap(0) + index = w_seqiter.index+1 + w_length = space.len(w_seqiter.w_seq) + # if length of sequence is less than index :exhaust iterator + if space.is_true(space.gt(space.wrap(w_seqiter.index), w_length)): + w_len = space.wrap(0) + w_seqiter.w_seq = None + else: + w_len =space.wrap(index) + if space.is_true(space.lt(w_len,space.wrap(0))): + w_len = space.wrap(0) return w_len register_all(vars()) Modified: pypy/dist/pypy/objspace/std/itertype.py ============================================================================== --- pypy/dist/pypy/objspace/std/itertype.py (original) +++ pypy/dist/pypy/objspace/std/itertype.py Tue Aug 23 17:18:05 2005 @@ -1,6 +1,8 @@ from pypy.objspace.std.stdtypedef import * # ____________________________________________________________ - iter_typedef = StdTypeDef("sequenceiterator", ) + +reverse_iter_typedef = StdTypeDef("reversesequenceiterator", + ) Modified: pypy/dist/pypy/objspace/std/test/test_iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_iterobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_iterobject.py Tue Aug 23 17:18:05 2005 @@ -59,66 +59,25 @@ iter, C()) -class AppTest_IterObject: +class AppTest_IterObject(object): + def setup_method(self,method): + + self.iterable = '' - def check_iter(self,iterable): - it = iter(iterable) + def test_len(self):#,iterable): + self.iterable = (1,2,3,4) + it = iter(self.iterable) for i in reversed(range(len(it))): assert len(it) == i+1 x = it.next() - print x raises(StopIteration, it.next) assert len(it) == 0 - def test_iter_len_tuple(self): - iterable = (1,2,3,4) - it = iter(iterable) - for i in reversed(range(len(it))): - assert len(it) == i+1 - x = it.next() - print x - raises(StopIteration, it.next) - assert len(it) == 0 - - def test_iter_len_dict(self): - iterable = {1:1,2:2,3:3,4:4} - it = iter(iterable) - length = len(it) - for i in reversed(range(length)): - assert len(it) == i+1 - x = it.next() - raises(StopIteration, it.next) - assert len(it) == 0 - def test_iter_len_list(self): - iterable = [1,2,3,4] - it = iter(iterable) - for i in reversed(range(len(it))): - assert len(it) == i+1 - x = it.next() - print x - raises(StopIteration, it.next) - assert len(it) == 0 +class AppTest_lenTuple(AppTest_IterObject): - def test_iter_len_str(self): - iterable = 'Hello World' - it = iter(iterable) - for i in reversed(range(len(it))): - assert len(it) == i+1 - x = it.next() - print x - raises(StopIteration, it.next) - assert len(it) == 0 - - def test_iter_len_set(self): - iterable = set((1,2,3,4)) - it = iter(iterable) - for i in reversed(range(len(it))): - assert len(it) == i+1 - x = it.next() - print x - raises(StopIteration, it.next) - assert len(it) == 0 + def setup_method(self,method): + self.iterable = (1,2,3,4) def test_iter_len_deque(self): from collections import deque @@ -128,7 +87,7 @@ for i in reversed(range(len(it))): assert len(it) == i+1 x = it.next() - print x + raises(StopIteration, it.next) assert len(it) == 0 @@ -138,7 +97,6 @@ for i in reversed(range(len(it))): assert len(it) == i+1 x = it.next() - print x raises(StopIteration, it.next) assert len(it) == 0 @@ -154,3 +112,65 @@ assert len(it) == 0 raises(StopIteration, it.next) assert len(it) == 0 + + def test_mutation_list(self): + n = 5 + d = range(n) + it = iter(d) + it.next() + it.next() + assert len(it) == n-2 + d.append(n) + assert len(it) == n-1 # grow with append + d[1:] = [] + assert len(it) == 0 + assert list(it) == [] + d.extend(xrange(20)) + assert len(it) == 0 + + def test_mutation_list_reversed(self): + n = 5 + d = range(n) + it = reversed(d) + it.next() + it.next() + assert len(it) == n-2 + d.append(n) + assert len(it) == n-2 # Ignore append + d[1:] = [] + assert len(it) == 0 + assert list(it) == [] + d.extend(xrange(20)) + assert len(it) == 0 + + def test_mutation_seqiter(self): + from UserList import UserList + n = 5 + d = UserList(range(n)) + it = iter(d) + it.next() + it.next() + assert len(it) == n-2 + d.append(n) + assert len(it) == n-1 # grow with append + d[1:] = [] + assert len(it) == 0 + assert list(it) == [] + d.extend(xrange(20)) + assert len(it) == 0 + + def test_mutation_seqiter_reversed(self): + from UserList import UserList + n = 5 + d = UserList(range(n)) + it = reversed(d) + it.next() + it.next() + assert len(it) == n-2 + d.append(n) + assert len(it) == n-2 # ignore append + d[1:] = [] + assert len(it) == 0 + assert list(it) == [] + d.extend(xrange(20)) + assert len(it) == 0 From ale at codespeak.net Tue Aug 23 17:19:11 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 17:19:11 +0200 (CEST) Subject: [pypy-svn] r16291 - pypy/dist/lib-python Message-ID: <20050823151911.6DD1127B41@code1.codespeak.net> Author: ale Date: Tue Aug 23 17:19:10 2005 New Revision: 16291 Modified: pypy/dist/lib-python/failure_list.txt Log: update Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Tue Aug 23 17:19:10 2005 @@ -32,6 +32,7 @@ test_decorator fails because globals and locals are None in a nested function ? +test_enumerate FIXED by skippiing a test for an implementation detail . test_builtin - our compilers need to recognize BOM markers From jacob at codespeak.net Tue Aug 23 17:23:25 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Tue, 23 Aug 2005 17:23:25 +0200 (CEST) Subject: [pypy-svn] r16293 - in pypy/dist/lib-python/modified-2.4.1: . email test Message-ID: <20050823152325.1C6FB27B43@code1.codespeak.net> Author: jacob Date: Tue Aug 23 17:23:23 2005 New Revision: 16293 Added: pypy/dist/lib-python/modified-2.4.1/email/ pypy/dist/lib-python/modified-2.4.1/email/Charset.py pypy/dist/lib-python/modified-2.4.1/test/test_uu.py pypy/dist/lib-python/modified-2.4.1/uu.py (contents, props changed) Modified: pypy/dist/lib-python/modified-2.4.1/test/test_base64.py Log: Fixed regression bugs. The bugs in uu.py and Charset.py ought to be problems in CPython too. Added: pypy/dist/lib-python/modified-2.4.1/email/Charset.py ============================================================================== --- (empty file) +++ pypy/dist/lib-python/modified-2.4.1/email/Charset.py Tue Aug 23 17:23:23 2005 @@ -0,0 +1,370 @@ +# Copyright (C) 2001-2004 Python Software Foundation +# Author: Ben Gertzfield, Barry Warsaw +# Contact: email-sig at python.org + +import email.base64MIME +import email.quopriMIME +from email.Encoders import encode_7or8bit + + + +# Flags for types of header encodings +QP = 1 # Quoted-Printable +BASE64 = 2 # Base64 +SHORTEST = 3 # the shorter of QP and base64, but only for headers + +# In "=?charset?q?hello_world?=", the =?, ?q?, and ?= add up to 7 +MISC_LEN = 7 + +DEFAULT_CHARSET = 'us-ascii' + + + +# Defaults +CHARSETS = { + # input header enc body enc output conv + 'iso-8859-1': (QP, QP, None), + 'iso-8859-2': (QP, QP, None), + 'iso-8859-3': (QP, QP, None), + 'iso-8859-4': (QP, QP, None), + # iso-8859-5 is Cyrillic, and not especially used + # iso-8859-6 is Arabic, also not particularly used + # iso-8859-7 is Greek, QP will not make it readable + # iso-8859-8 is Hebrew, QP will not make it readable + 'iso-8859-9': (QP, QP, None), + 'iso-8859-10': (QP, QP, None), + # iso-8859-11 is Thai, QP will not make it readable + 'iso-8859-13': (QP, QP, None), + 'iso-8859-14': (QP, QP, None), + 'iso-8859-15': (QP, QP, None), + 'windows-1252':(QP, QP, None), + 'viscii': (QP, QP, None), + 'us-ascii': (None, None, None), + 'big5': (BASE64, BASE64, None), + 'gb2312': (BASE64, BASE64, None), + 'euc-jp': (BASE64, None, 'iso-2022-jp'), + 'shift_jis': (BASE64, None, 'iso-2022-jp'), + 'iso-2022-jp': (BASE64, None, None), + 'koi8-r': (BASE64, BASE64, None), + 'utf-8': (SHORTEST, BASE64, 'utf-8'), + # We're making this one up to represent raw unencoded 8-bit + '8bit': (None, BASE64, 'utf-8'), + } + +# Aliases for other commonly-used names for character sets. Map +# them to the real ones used in email. +ALIASES = { + 'latin_1': 'iso-8859-1', + 'latin-1': 'iso-8859-1', + 'latin_2': 'iso-8859-2', + 'latin-2': 'iso-8859-2', + 'latin_3': 'iso-8859-3', + 'latin-3': 'iso-8859-3', + 'latin_4': 'iso-8859-4', + 'latin-4': 'iso-8859-4', + 'latin_5': 'iso-8859-9', + 'latin-5': 'iso-8859-9', + 'latin_6': 'iso-8859-10', + 'latin-6': 'iso-8859-10', + 'latin_7': 'iso-8859-13', + 'latin-7': 'iso-8859-13', + 'latin_8': 'iso-8859-14', + 'latin-8': 'iso-8859-14', + 'latin_9': 'iso-8859-15', + 'latin-9': 'iso-8859-15', + 'cp949': 'ks_c_5601-1987', + 'euc_jp': 'euc-jp', + 'euc_kr': 'euc-kr', + 'ascii': 'us-ascii', + } + + +# Map charsets to their Unicode codec strings. +CODEC_MAP = { + 'gb2312': 'eucgb2312_cn', + 'big5': 'big5_tw', + # Hack: We don't want *any* conversion for stuff marked us-ascii, as all + # sorts of garbage might be sent to us in the guise of 7-bit us-ascii. + # Let that stuff pass through without conversion to/from Unicode. + 'us-ascii': None, + } + + + +# Convenience functions for extending the above mappings +def add_charset(charset, header_enc=None, body_enc=None, output_charset=None): + """Add character set properties to the global registry. + + charset is the input character set, and must be the canonical name of a + character set. + + Optional header_enc and body_enc is either Charset.QP for + quoted-printable, Charset.BASE64 for base64 encoding, Charset.SHORTEST for + the shortest of qp or base64 encoding, or None for no encoding. SHORTEST + is only valid for header_enc. It describes how message headers and + message bodies in the input charset are to be encoded. Default is no + encoding. + + Optional output_charset is the character set that the output should be + in. Conversions will proceed from input charset, to Unicode, to the + output charset when the method Charset.convert() is called. The default + is to output in the same character set as the input. + + Both input_charset and output_charset must have Unicode codec entries in + the module's charset-to-codec mapping; use add_codec(charset, codecname) + to add codecs the module does not know about. See the codecs module's + documentation for more information. + """ + if body_enc == SHORTEST: + raise ValueError('SHORTEST not allowed for body_enc') + CHARSETS[charset] = (header_enc, body_enc, output_charset) + + +def add_alias(alias, canonical): + """Add a character set alias. + + alias is the alias name, e.g. latin-1 + canonical is the character set's canonical name, e.g. iso-8859-1 + """ + ALIASES[alias] = canonical + + +def add_codec(charset, codecname): + """Add a codec that map characters in the given charset to/from Unicode. + + charset is the canonical name of a character set. codecname is the name + of a Python codec, as appropriate for the second argument to the unicode() + built-in, or to the encode() method of a Unicode string. + """ + CODEC_MAP[charset] = codecname + + + +class Charset: + """Map character sets to their email properties. + + This class provides information about the requirements imposed on email + for a specific character set. It also provides convenience routines for + converting between character sets, given the availability of the + applicable codecs. Given a character set, it will do its best to provide + information on how to use that character set in an email in an + RFC-compliant way. + + Certain character sets must be encoded with quoted-printable or base64 + when used in email headers or bodies. Certain character sets must be + converted outright, and are not allowed in email. Instances of this + module expose the following information about a character set: + + input_charset: The initial character set specified. Common aliases + are converted to their `official' email names (e.g. latin_1 + is converted to iso-8859-1). Defaults to 7-bit us-ascii. + + header_encoding: If the character set must be encoded before it can be + used in an email header, this attribute will be set to + Charset.QP (for quoted-printable), Charset.BASE64 (for + base64 encoding), or Charset.SHORTEST for the shortest of + QP or BASE64 encoding. Otherwise, it will be None. + + body_encoding: Same as header_encoding, but describes the encoding for the + mail message's body, which indeed may be different than the + header encoding. Charset.SHORTEST is not allowed for + body_encoding. + + output_charset: Some character sets must be converted before the can be + used in email headers or bodies. If the input_charset is + one of them, this attribute will contain the name of the + charset output will be converted to. Otherwise, it will + be None. + + input_codec: The name of the Python codec used to convert the + input_charset to Unicode. If no conversion codec is + necessary, this attribute will be None. + + output_codec: The name of the Python codec used to convert Unicode + to the output_charset. If no conversion codec is necessary, + this attribute will have the same value as the input_codec. + """ + def __init__(self, input_charset=DEFAULT_CHARSET): + # RFC 2046, $4.1.2 says charsets are not case sensitive. We coerce to + # unicode because its .lower() is locale insensitive. + input_charset = str(unicode(input_charset, 'ascii').lower()) + # Set the input charset after filtering through the aliases + self.input_charset = ALIASES.get(input_charset, input_charset) + # We can try to guess which encoding and conversion to use by the + # charset_map dictionary. Try that first, but let the user override + # it. + henc, benc, conv = CHARSETS.get(self.input_charset, + (SHORTEST, BASE64, None)) + if not conv: + conv = self.input_charset + # Set the attributes, allowing the arguments to override the default. + self.header_encoding = henc + self.body_encoding = benc + self.output_charset = ALIASES.get(conv, conv) + # Now set the codecs. If one isn't defined for input_charset, + # guess and try a Unicode codec with the same name as input_codec. + self.input_codec = CODEC_MAP.get(self.input_charset, + self.input_charset) + self.output_codec = CODEC_MAP.get(self.output_charset, + self.output_charset) + + def __str__(self): + return self.input_charset.lower() + + __repr__ = __str__ + + def __eq__(self, other): + return str(self) == str(other).lower() + + def __ne__(self, other): + return not self.__eq__(other) + + def get_body_encoding(self): + """Return the content-transfer-encoding used for body encoding. + + This is either the string `quoted-printable' or `base64' depending on + the encoding used, or it is a function in which case you should call + the function with a single argument, the Message object being + encoded. The function should then set the Content-Transfer-Encoding + header itself to whatever is appropriate. + + Returns "quoted-printable" if self.body_encoding is QP. + Returns "base64" if self.body_encoding is BASE64. + Returns "7bit" otherwise. + """ + assert self.body_encoding <> SHORTEST + if self.body_encoding == QP: + return 'quoted-printable' + elif self.body_encoding == BASE64: + return 'base64' + else: + return encode_7or8bit + + def convert(self, s): + """Convert a string from the input_codec to the output_codec.""" + if self.input_codec <> self.output_codec: + return unicode(s, self.input_codec).encode(self.output_codec) + else: + return s + + def to_splittable(self, s): + """Convert a possibly multibyte string to a safely splittable format. + + Uses the input_codec to try and convert the string to Unicode, so it + can be safely split on character boundaries (even for multibyte + characters). + + Returns the string as-is if it isn't known how to convert it to + Unicode with the input_charset. + + Characters that could not be converted to Unicode will be replaced + with the Unicode replacement character U+FFFD. + """ + if isinstance(s, unicode) or self.input_codec is None: + return s + try: + return unicode(s, self.input_codec, 'replace') + except LookupError: + # Input codec not installed on system, so return the original + # string unchanged. + return s + + def from_splittable(self, ustr, to_output=True): + """Convert a splittable string back into an encoded string. + + Uses the proper codec to try and convert the string from Unicode back + into an encoded format. Return the string as-is if it is not Unicode, + or if it could not be converted from Unicode. + + Characters that could not be converted from Unicode will be replaced + with an appropriate character (usually '?'). + + If to_output is True (the default), uses output_codec to convert to an + encoded format. If to_output is False, uses input_codec. + """ + if to_output: + codec = self.output_codec + else: + codec = self.input_codec + if not isinstance(ustr, unicode) or codec is None: + return ustr + try: + return ustr.encode(codec, 'replace') + except LookupError: + # Output codec not installed + return ustr + + def get_output_charset(self): + """Return the output character set. + + This is self.output_charset if that is not None, otherwise it is + self.input_charset. + """ + return self.output_charset or self.input_charset + + def encoded_header_len(self, s): + """Return the length of the encoded header string.""" + cset = self.get_output_charset() + # The len(s) of a 7bit encoding is len(s) + if self.header_encoding == BASE64: + return email.base64MIME.base64_len(s) + len(cset) + MISC_LEN + elif self.header_encoding == QP: + return email.quopriMIME.header_quopri_len(s) + len(cset) + MISC_LEN + elif self.header_encoding == SHORTEST: + lenb64 = email.base64MIME.base64_len(s) + lenqp = email.quopriMIME.header_quopri_len(s) + return min(lenb64, lenqp) + len(cset) + MISC_LEN + else: + return len(s) + + def header_encode(self, s, convert=False): + """Header-encode a string, optionally converting it to output_charset. + + If convert is True, the string will be converted from the input + charset to the output charset automatically. This is not useful for + multibyte character sets, which have line length issues (multibyte + characters must be split on a character, not a byte boundary); use the + high-level Header class to deal with these issues. convert defaults + to False. + + The type of encoding (base64 or quoted-printable) will be based on + self.header_encoding. + """ + cset = self.get_output_charset() + if convert: + s = self.convert(s) + # 7bit/8bit encodings return the string unchanged (modulo conversions) + if self.header_encoding == BASE64: + return email.base64MIME.header_encode(s, cset) + elif self.header_encoding == QP: + return email.quopriMIME.header_encode(s, cset, maxlinelen=None) + elif self.header_encoding == SHORTEST: + lenb64 = email.base64MIME.base64_len(s) + lenqp = email.quopriMIME.header_quopri_len(s) + if lenb64 < lenqp: + return email.base64MIME.header_encode(s, cset) + else: + return email.quopriMIME.header_encode(s, cset, maxlinelen=None) + else: + return s + + def body_encode(self, s, convert=True): + """Body-encode a string and convert it to output_charset. + + If convert is True (the default), the string will be converted from + the input charset to output charset automatically. Unlike + header_encode(), there are no issues with byte boundaries and + multibyte charsets in email bodies, so this is usually pretty safe. + + The type of encoding (base64 or quoted-printable) will be based on + self.body_encoding. + """ + if convert: + s = self.convert(s) + # 7bit/8bit encodings return the string unchanged (module conversions) + if self.body_encoding is BASE64: + return email.base64MIME.body_encode(s) + elif self.body_encoding is QP: + return email.quopriMIME.body_encode(s) + else: + return s Modified: pypy/dist/lib-python/modified-2.4.1/test/test_base64.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_base64.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_base64.py Tue Aug 23 17:23:23 2005 @@ -117,9 +117,19 @@ # Test with 'URL safe' alternative characters eq(base64.urlsafe_b64decode('01a-b_cd'), '\xd3V\xbeo\xf7\x1d') + + # This test is testing an implementation specific detail. + # In our implementation, we make a best attempt to translate + # strings with broken encoding back to their original form. + # Since the user will most likely be interested in what remains + # of a message which has been broken in transmission, this seems to + # be the most reasonable thing to do. + # In pypy we disable this test! + ''' def test_b64decode_error(self): self.assertRaises(TypeError, base64.b64decode, 'abc') - + ''' + def test_b32encode(self): eq = self.assertEqual eq(base64.b32encode(''), '') Added: pypy/dist/lib-python/modified-2.4.1/test/test_uu.py ============================================================================== --- (empty file) +++ pypy/dist/lib-python/modified-2.4.1/test/test_uu.py Tue Aug 23 17:23:23 2005 @@ -0,0 +1,172 @@ +""" +Tests for uu module. +Nick Mathewson +""" + +import unittest +from test import test_support + +import sys, os, uu, cStringIO +import uu +from StringIO import StringIO + +plaintext = "The smooth-scaled python crept over the sleeping dog\n" + +encodedtext = """\ +M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P +(:6YG(&1O9PH """ + +encodedtextwrapped = "begin %03o %s\n" + encodedtext.replace("%", "%%") + "\n \nend\n" + +class UUTest(unittest.TestCase): + + def test_encode(self): + inp = cStringIO.StringIO(plaintext) + out = cStringIO.StringIO() + uu.encode(inp, out, "t1") + self.assertEqual(out.getvalue(), encodedtextwrapped % (0666, "t1")) + inp = cStringIO.StringIO(plaintext) + out = cStringIO.StringIO() + uu.encode(inp, out, "t1", 0644) + self.assertEqual(out.getvalue(), encodedtextwrapped % (0644, "t1")) + + def test_decode(self): + inp = cStringIO.StringIO(encodedtextwrapped % (0666, "t1")) + out = cStringIO.StringIO() + uu.decode(inp, out) + self.assertEqual(out.getvalue(), plaintext) + inp = cStringIO.StringIO( + "UUencoded files may contain many lines,\n" + + "even some that have 'begin' in them.\n" + + encodedtextwrapped % (0666, "t1") + ) + out = cStringIO.StringIO() + uu.decode(inp, out) + self.assertEqual(out.getvalue(), plaintext) + + def test_truncatedinput(self): + inp = cStringIO.StringIO("begin 644 t1\n" + encodedtext) + out = cStringIO.StringIO() + try: + uu.decode(inp, out) + self.fail("No exception thrown") + except uu.Error, e: + self.assertEqual(str(e), "Truncated input file") + + def test_missingbegin(self): + inp = cStringIO.StringIO("") + out = cStringIO.StringIO() + try: + uu.decode(inp, out) + self.fail("No exception thrown") + except uu.Error, e: + self.assertEqual(str(e), "No valid begin line found in input file") + +class UUStdIOTest(unittest.TestCase): + + def setUp(self): + self.stdin = sys.stdin + self.stdout = sys.stdout + + def tearDown(self): + sys.stdin = self.stdin + sys.stdout = self.stdout + + def test_encode(self): + sys.stdin = cStringIO.StringIO(plaintext) + sys.stdout = cStringIO.StringIO() + uu.encode("-", "-", "t1", 0666) + self.assertEqual( + sys.stdout.getvalue(), + encodedtextwrapped % (0666, "t1") + ) + + def test_decode(self): + sys.stdin = cStringIO.StringIO(encodedtextwrapped % (0666, "t1")) + sys.stdout = cStringIO.StringIO() + uu.decode("-", "-") + self.assertEqual(sys.stdout.getvalue(), plaintext) + +class UUFileTest(unittest.TestCase): + + def _kill(self, f): + # close and remove file + try: + f.close() + except (SystemExit, KeyboardInterrupt): + raise + except: + pass + try: + os.unlink(f.name) + except (SystemExit, KeyboardInterrupt): + raise + except: + pass + + def setUp(self): + self.tmpin = test_support.TESTFN + "i" + self.tmpout = test_support.TESTFN + "o" + + def tearDown(self): + del self.tmpin + del self.tmpout + + def test_encode(self): + try: + fin = open(self.tmpin, 'wb') + fin.write(plaintext) + fin.close() + + fin = open(self.tmpin, 'rb') + fout = open(self.tmpout, 'w') + uu.encode(fin, fout, self.tmpin, mode=0644) + fin.close() + fout.close() + + fout = open(self.tmpout, 'r') + s = fout.read() + fout.close() + self.assertEqual(s, encodedtextwrapped % (0644, self.tmpin)) + finally: + self._kill(fin) + self._kill(fout) + + def test_decode(self): + try: + f = open(self.tmpin, 'wb') + f.write(encodedtextwrapped % (0644, self.tmpout)) + f.close() + + f = open(self.tmpin, 'rb') + uu.decode(f) + f.close() + + f = open(self.tmpout, 'r') + s = f.read() + f.close() + self.assertEqual(s, plaintext) + # XXX is there an xp way to verify the mode? + finally: + self._kill(f) + + def test_decodetwice(self): + # Verify that decode() will refuse to overwrite an existing file + try: + f = cStringIO.StringIO(encodedtextwrapped % (0644, self.tmpout)) + + f = open(self.tmpin, 'rb') + uu.decode(f) + f.close() + + f = open(self.tmpin, 'rb') + self.assertRaises(uu.Error, uu.decode, f) + f.close() + finally: + self._kill(f) + +def test_main(): + test_support.run_unittest(UUTest, UUStdIOTest, UUFileTest) + +if __name__=="__main__": + test_main() Added: pypy/dist/lib-python/modified-2.4.1/uu.py ============================================================================== --- (empty file) +++ pypy/dist/lib-python/modified-2.4.1/uu.py Tue Aug 23 17:23:23 2005 @@ -0,0 +1,197 @@ +#! /usr/bin/env python + +# Copyright 1994 by Lance Ellinghouse +# Cathedral City, California Republic, United States of America. +# All Rights Reserved +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose and without fee is hereby granted, +# provided that the above copyright notice appear in all copies and that +# both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of Lance Ellinghouse +# not be used in advertising or publicity pertaining to distribution +# of the software without specific, written prior permission. +# LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Modified by Jack Jansen, CWI, July 1995: +# - Use binascii module to do the actual line-by-line conversion +# between ascii and binary. This results in a 1000-fold speedup. The C +# version is still 5 times faster, though. +# - Arguments more compliant with python standard + +"""Implementation of the UUencode and UUdecode functions. + +encode(in_file, out_file [,name, mode]) +decode(in_file [, out_file, mode]) +""" + +import binascii +import os +import sys +from types import StringType + +__all__ = ["Error", "encode", "decode"] + +class Error(Exception): + pass + +def encode(in_file, out_file, name=None, mode=None): + """Uuencode file""" + # + # If in_file is a pathname open it and change defaults + # + if in_file == '-': + in_file = sys.stdin + elif isinstance(in_file, StringType): + if name is None: + name = os.path.basename(in_file) + if mode is None: + try: + mode = os.stat(in_file).st_mode + except AttributeError: + pass + in_file = open(in_file, 'rb') + # + # Open out_file if it is a pathname + # + if out_file == '-': + out_file = sys.stdout + elif isinstance(out_file, StringType): + out_file = open(out_file, 'w') + # + # Set defaults for name and mode + # + if name is None: + name = '-' + if mode is None: + mode = 0666 + # + # Write the data + # + out_file.write('begin %o %s\n' % ((mode&0777),name)) + str = in_file.read(45) + while len(str) > 0: + out_file.write(binascii.b2a_uu(str)) + str = in_file.read(45) + out_file.write(' \nend\n') + + +def decode(in_file, out_file=None, mode=None, quiet=0): + """Decode uuencoded file""" + # + # Open the input file, if needed. + # + if in_file == '-': + in_file = sys.stdin + elif isinstance(in_file, StringType): + in_file = open(in_file) + # + # Read until a begin is encountered or we've exhausted the file + # + while 1: + hdr = in_file.readline() + if not hdr: + raise Error, 'No valid begin line found in input file' + if hdr[:5] != 'begin': + continue + hdrfields = hdr.split(" ", 2) + if len(hdrfields) == 3 and hdrfields[0] == 'begin': + try: + int(hdrfields[1], 8) + break + except ValueError: + pass + if out_file is None: + out_file = hdrfields[2].rstrip() + if os.path.exists(out_file): + raise Error, 'Cannot overwrite existing file: %s' % out_file + if mode is None: + mode = int(hdrfields[1], 8) + # + # Open the output file + # + if out_file == '-': + out_file = sys.stdout + elif isinstance(out_file, StringType): + fp = open(out_file, 'wb') + try: + os.chmod(out_file, mode) + except AttributeError: + pass + out_file = fp + # + # Main decoding loop + # + s = in_file.readline() + while s and s.strip() != 'end': + try: + data = binascii.a2b_uu(s) + except binascii.Error, v: + # Workaround for broken uuencoders by /Fredrik Lundh + nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3 + data = binascii.a2b_uu(s[:nbytes]) + if not quiet: + sys.stderr.write("Warning: %s\n" % str(v)) + out_file.write(data) + s = in_file.readline() + if not s: + raise Error, 'Truncated input file' + + out_file.flush() + try: + fp.close() # If we create the file, don't leave the descriptor open + except UnboundLocalError: + pass + +def test(): + """uuencode/uudecode main program""" + import getopt + + dopt = 0 + topt = 0 + input = sys.stdin + output = sys.stdout + ok = 1 + try: + optlist, args = getopt.getopt(sys.argv[1:], 'dt') + except getopt.error: + ok = 0 + if not ok or len(args) > 2: + print 'Usage:', sys.argv[0], '[-d] [-t] [input [output]]' + print ' -d: Decode (in stead of encode)' + print ' -t: data is text, encoded format unix-compatible text' + sys.exit(1) + + for o, a in optlist: + if o == '-d': dopt = 1 + if o == '-t': topt = 1 + + if len(args) > 0: + input = args[0] + if len(args) > 1: + output = args[1] + + if dopt: + if topt: + if isinstance(output, StringType): + output = open(output, 'w') + else: + print sys.argv[0], ': cannot do -t to stdout' + sys.exit(1) + decode(input, output) + else: + if topt: + if isinstance(input, StringType): + input = open(input, 'r') + else: + print sys.argv[0], ': cannot do -t from stdin' + sys.exit(1) + encode(input, output) + +if __name__ == '__main__': + test() From tismer at codespeak.net Tue Aug 23 17:32:41 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 17:32:41 +0200 (CEST) Subject: [pypy-svn] r16294 - in pypy/dist/pypy: fakecompiler interpreter lib/_stablecompiler Message-ID: <20050823153241.D6DCD27B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 17:32:39 2005 New Revision: 16294 Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/lib/_stablecompiler/apphook.py Log: had to change the way to build the compilers. Everything is done at initialization time. When compiling, we check which compiler to use. Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py ============================================================================== --- pypy/dist/pypy/fakecompiler/fakecompiler.py (original) +++ pypy/dist/pypy/fakecompiler/fakecompiler.py Tue Aug 23 17:32:39 2005 @@ -2,17 +2,6 @@ DUMPFILE = 'this_is_the_marshal_file' -def fakeapplevelcompile(tuples, filename, mode): - done = False - data = marshal.dumps( (tuples, filename, mode, done) ) - file(DUMPFILE, "wb").write(data) - os.system('%s fakecompiler.py' % get_python()) - data = file(DUMPFILE, "rb").read() - code, filename, mode, done = marshal.loads(data) - if not done: - raise ValueError, "could not fake compile!" - return code - def reallycompile(tuples, filename, mode): return parser.compileast(parser.tuple2ast(tuples), filename) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 17:32:39 2005 @@ -244,25 +244,23 @@ debug_print(" done") def _load_compilers(self): - compile1 = self.space.appexec([], r'''(): + self.w_compileapp = self.space.appexec([], r'''(): from _stablecompiler import apphook return apphook.applevelcompile ''') - compile2 = self.w_applevelcompile = self.space.appexec([], r'''(): - import os + self.w_compilefake = self.space.appexec([], r'''(): from _stablecompiler import apphook - if os.path.exists('fakecompiler.py'): - print "faking compiler, because fakecompiler.py is in the current dir" - import fakecompiler - return fakecompiler.fakeapplevelcompile - else: - return apphook.applevelcompile + return apphook.fakeapplevelcompile ''') - self.applevelcompile_w = { - 'single': compile1, - 'eval': compile2, - 'exec': compile2, - } + + def _get_compiler(self, mode): + from pypy.interpreter.error import debug_print + import os + if os.path.exists('fakecompiler.py') and mode != 'single': + debug_print("faking compiler, because fakecompiler.py is in the current dir") + return self.w_compilefake + else: + return self.w_compileapp def compile_parse_result(self, parse_result, filename, mode): space = self.space @@ -282,7 +280,7 @@ w_nested_tuples, space.wrap(source_encoding)]) - w_code = space.call_function(self.applevelcompile_w[mode], + w_code = space.call_function(self._get_compiler(mode), w_nested_tuples, space.wrap(filename), space.wrap(mode)) Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Tue Aug 23 17:32:39 2005 @@ -20,3 +20,20 @@ else: # mode == 'eval': codegenerator = ExpressionCodeGenerator(tree) return codegenerator.getCode() + +# temporary fake stuff, to allow to use the translated +# PyPy for testing. + +DUMPFILE = 'this_is_the_marshal_file' + +def fakeapplevelcompile(tuples, filename, mode): + import os, marshal + done = False + data = marshal.dumps( (tuples, filename, mode, done) ) + file(DUMPFILE, "wb").write(data) + os.system('%s fakecompiler.py' % get_python()) + data = file(DUMPFILE, "rb").read() + code, filename, mode, done = marshal.loads(data) + if not done: + raise ValueError, "could not fake compile!" + return code From ale at codespeak.net Tue Aug 23 17:39:41 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 17:39:41 +0200 (CEST) Subject: [pypy-svn] r16296 - pypy/dist/pypy/objspace/std Message-ID: <20050823153941.8F06A27B41@code1.codespeak.net> Author: ale Date: Tue Aug 23 17:39:40 2005 New Revision: 16296 Modified: pypy/dist/pypy/objspace/std/model.py Log: forgot to add reverse sequenceiter to typeorder Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Tue Aug 23 17:39:40 2005 @@ -72,6 +72,7 @@ longobject.W_LongObject: [], noneobject.W_NoneObject: [], iterobject.W_SeqIterObject: [], + iterobject.W_ReverseSeqIterObject: [], unicodeobject.W_UnicodeObject: [], dictproxyobject.W_DictProxyObject: [], pypy.interpreter.pycode.PyCode: [], From tismer at codespeak.net Tue Aug 23 17:41:12 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 17:41:12 +0200 (CEST) Subject: [pypy-svn] r16297 - in pypy/dist/pypy: fakecompiler lib/_stablecompiler Message-ID: <20050823154112.0FA7827B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 17:41:11 2005 New Revision: 16297 Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py pypy/dist/pypy/lib/_stablecompiler/apphook.py Log: again failed a little bit... (not my day) Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py ============================================================================== --- pypy/dist/pypy/fakecompiler/fakecompiler.py (original) +++ pypy/dist/pypy/fakecompiler/fakecompiler.py Tue Aug 23 17:41:11 2005 @@ -5,12 +5,6 @@ def reallycompile(tuples, filename, mode): return parser.compileast(parser.tuple2ast(tuples), filename) -def get_python(): - try: - return file('pythonname').read().strip() - except IOError: - raise ValueError, "I need a local file 'pythonname'" - if __name__ == '__main__': tuples, filename, mode, done = marshal.load(file(DUMPFILE, "rb")) code = reallycompile(tuples, filename, mode) Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Tue Aug 23 17:41:11 2005 @@ -37,3 +37,9 @@ if not done: raise ValueError, "could not fake compile!" return code + +def get_python(): + try: + return file('pythonname').read().strip() + except IOError: + raise ValueError, "I need a local file 'pythonname'" From pedronis at codespeak.net Tue Aug 23 17:41:36 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 23 Aug 2005 17:41:36 +0200 (CEST) Subject: [pypy-svn] r16298 - pypy/dist/pypy/translator/c Message-ID: <20050823154136.C924B27B41@code1.codespeak.net> Author: pedronis Date: Tue Aug 23 17:41:35 2005 New Revision: 16298 Modified: pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/node.py Log: progress moving refcounting out of node.py (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Aug 23 17:41:35 2005 @@ -74,10 +74,6 @@ result.append(decrefstmt) result.append('}') - - def rtti_type(self): - return 'void (@)(void *)' # void dealloc_xx(struct xx *) - def gcheader_field_name(self, defnode): return 'refcount' @@ -152,3 +148,14 @@ array_gcheader_initialitionexpr = common_gcheader_initializationexpr + # for rtti node + + def rtti_type(self): + return 'void (@)(void *)' # void dealloc_xx(struct xx *) + + def rtti_node(self, defnode, node): + node.typename = 'void (@)(void *)' + node.implementationtypename = 'void (@)(struct %s *)' % ( + defnode.name,) + node.name = defnode.gcinfo.static_deallocator + node.ptrname = '((void (*)(void *)) %s)' % (node.name,) Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Aug 23 17:41:35 2005 @@ -22,12 +22,8 @@ class StructDefNode: gcheader = None - gcinfo = None - #deallocator = None - #static_deallocator = None - def __init__(self, db, STRUCT, varlength=1): self.db = db self.STRUCT = STRUCT @@ -85,7 +81,7 @@ except ValueError: pass - # do we need deallocator(s)? + # let the gcpolicy do its own setup if varlength == 1: self.db.gcpolicy.struct_setup(self, rtti) @@ -124,7 +120,7 @@ if gcinfo.static_deallocator: yield 'void %s(struct %s *p) {' % (gcinfo.static_deallocator, self.name) - for line in self.deallocator_lines('(*p)'): + for line in self.visitor_lines('(*p)', generic_dealloc): yield '\t' + line yield '\tOP_FREE(p);' yield '}' @@ -141,14 +137,18 @@ yield '\t\tstaticdealloc(p);' yield '}' - def deallocator_lines(self, prefix): # xxx xxx rename, re-factor generic_dealloc use + def deallocator_lines(self, prefix): + for line in self.visitor_lines(prefix, generic_dealloc): + yield line + + def visitor_lines(self, prefix, on_field): STRUCT = self.STRUCT for name in STRUCT._names: FIELD_T = self.c_struct_field_type(name) cname = self.c_struct_field_name(name) - for line in generic_dealloc(self.db, - '%s.%s' % (prefix, cname), - FIELD_T): + for line in on_field(self.db, + '%s.%s' % (prefix, cname), + FIELD_T): yield line def debug_offsets(self): @@ -197,7 +197,7 @@ varlength = self.varlength self.itemtypename = db.gettype(ARRAY.OF, who_asks=self) - # is a specific deallocator needed? + # let the gcpolicy do its own setup if varlength == 1: self.db.gcpolicy.array_setup(self) @@ -227,12 +227,16 @@ gcinfo = self.gcinfo if gcinfo.deallocator: yield 'void %s(struct %s *a) {' % (gcinfo.deallocator, self.name) - for line in self.deallocator_lines('(*a)'): + for line in self.visitor_lines('(*a)', generic_dealloc): yield '\t' + line yield '\tOP_FREE(a);' yield '}' - def deallocator_lines(self, prefix): # xxx xxx rename, re-factor generic_dealloc use + def deallocator_lines(self, prefix): + for line in self.visitor_lines(prefix, generic_dealloc): + yield line + + def visitor_lines(self, prefix, on_item): 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' @@ -241,7 +245,7 @@ while prefix.find(varname) >= 0: i += 1 varname = 'p%d' % i - body = list(generic_dealloc(self.db, '(*%s)' % varname, ARRAY.OF)) + body = list(on_item(self.db, '(*%s)' % varname, ARRAY.OF)) if body: yield '{' yield '\t%s = %s.items;' % (cdecl(self.itemtypename, '*' + varname), @@ -280,9 +284,6 @@ def setup(self): pass - def deallocator_lines(self, prefix): - yield 'RPyOpaqueDealloc_%s(&(%s));' % (self.T.tag, prefix) - def definition(self, phase): return [] @@ -294,8 +295,11 @@ yield line elif isinstance(T, ContainerType): defnode = db.gettypedefnode(T) - for line in defnode.deallocator_lines(expr): - yield line + if isinstance(defnode, ExtTypeOpaqueDefNode): + yield 'RPyOpaqueDealloc_%s(&(%s));' % (defnode.T.tag, expr) + else: + for line in defnode.visitor_lines(expr, generic_dealloc): + yield line # ____________________________________________________________ @@ -551,20 +555,17 @@ class OpaqueNode(ContainerNode): globalcontainer = True - typename = 'void (@)(void *)' includes = () - def __init__(self, db, T, obj): # xxx this supplies rtti value -> gc + def __init__(self, db, T, obj): assert T == RuntimeTypeInfo assert isinstance(obj.about, GcStruct) self.db = db self.T = T self.obj = obj defnode = db.gettypedefnode(obj.about) - self.implementationtypename = 'void (@)(struct %s *)' % ( - defnode.name,) - self.name = defnode.gcinfo.static_deallocator - self.ptrname = '((void (*)(void *)) %s)' % (self.name,) + + self.db.gcpolicy.rtti_node(defnode, self) def enum_dependencies(self): return [] From arigo at codespeak.net Tue Aug 23 17:49:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 17:49:08 +0200 (CEST) Subject: [pypy-svn] r16299 - pypy/dist/pypy/annotation Message-ID: <20050823154908.B8E1127B41@code1.codespeak.net> Author: arigo Date: Tue Aug 23 17:49:07 2005 New Revision: 16299 Modified: pypy/dist/pypy/annotation/binaryop.py Log: (rxe, arigo) union() of two SomeExternalObjects was missing. Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Tue Aug 23 17:49:07 2005 @@ -10,6 +10,7 @@ from pypy.annotation.model import SomeTuple, SomeImpossibleValue from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat +from pypy.annotation.model import SomeExternalObject from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess from pypy.annotation.model import unionof, UnionError, set, missing_operation, TLS from pypy.annotation.model import add_knowntypedata, merge_knowntypedata @@ -601,6 +602,13 @@ def getitem((pbc, o)): return SomeImpossibleValue() +class __extend__(pairtype(SomeExternalObject, SomeExternalObject)): + def union((ext1, ext2)): + if ext1.knowntype == ext2.knowntype: + return SomeExternalObject(ext1.knowntype) + return SomeObject() + +# ____________________________________________________________ # annotation of low-level types from pypy.annotation.model import SomePtr, ll_to_annotation, annotation_to_lltype From tismer at codespeak.net Tue Aug 23 17:51:53 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 17:51:53 +0200 (CEST) Subject: [pypy-svn] r16300 - pypy/dist/pypy/objspace/std Message-ID: <20050823155153.45ED227B41@code1.codespeak.net> Author: tismer Date: Tue Aug 23 17:51:51 2005 New Revision: 16300 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py Log: removed unwrap, for some reason it is seen, now. Let's compile and see where it is used. Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Tue Aug 23 17:51:51 2005 @@ -21,10 +21,10 @@ """ representation for debugging purposes """ return "%s(%r)" % (w_self.__class__.__name__, w_self._value) - def unwrap(w_self): - # For faked functions taking unicodearguments. - # Remove when we no longer need faking. - return u''.join(w_self._value) +## def unwrap(w_self): +## # For faked functions taking unicodearguments. +## # Remove when we no longer need faking. +## return u''.join(w_self._value) registerimplementation(W_UnicodeObject) From arigo at codespeak.net Tue Aug 23 17:55:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 17:55:30 +0200 (CEST) Subject: [pypy-svn] r16302 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20050823155530.BCADF27B41@code1.codespeak.net> Author: arigo Date: Tue Aug 23 17:55:27 2005 New Revision: 16302 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/src/ll_thread.h pypy/dist/pypy/translator/c/src/main.h pypy/dist/pypy/translator/c/src/module.h pypy/dist/pypy/translator/c/src/thread_nt.h pypy/dist/pypy/translator/c/src/thread_pthread.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: (rxe, arigo) Support in genc for prebuilt external objects -- in this case, prebuilt locks. Split OpaqueNode into xxx_OpaqueNode classes for the various usages of opaque prebuilt constants. Lots of changes; this required producing and calling start-up code to the generated C source. Each thread_*.h needs to provide in the RPyOpaque_INITEXPR_ThreadLock macro an expression suitable for a lock initializer (though RPyThreadLockInit() is still called on the structure from the start-up code). Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Aug 23 17:55:27 2005 @@ -5,7 +5,7 @@ from pypy.translator.c.primitive import PrimitiveName, PrimitiveType from pypy.translator.c.primitive import PrimitiveErrorValue from pypy.translator.c.node import StructDefNode, ArrayDefNode -from pypy.translator.c.node import ContainerNodeClass, ExtTypeOpaqueDefNode +from pypy.translator.c.node import ContainerNodeFactory, ExtTypeOpaqueDefNode from pypy.translator.c.support import cdecl, CNameManager, ErrorValue from pypy.translator.c.pyobj import PyObjMaker from pypy.translator.c import gc @@ -92,8 +92,8 @@ node = self.containernodes[container] except KeyError: T = typeOf(container) - nodecls = ContainerNodeClass[T.__class__] - node = nodecls(self, T, container) + nodefactory = ContainerNodeFactory[T.__class__] + node = nodefactory(self, T, container) self.containernodes[container] = node self.containerlist.append(node) return node Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Aug 23 17:55:27 2005 @@ -159,6 +159,23 @@ print >> f, line blank = True +def gen_startupcode(f, database): + # generate the start-up code and put it into a function + print >> f, 'char *RPython_StartupCode(void) {' + print >> f, '\tchar *error = NULL;' + firsttime = True + for node in database.containerlist: + lines = list(node.startupcode()) + if lines: + if firsttime: + firsttime = False + else: + print >> f, '\tif (error) return error;' + for line in lines: + print >> f, '\t'+line + print >> f, '\treturn error;' + print >> f, '}' + def gen_source_standalone(database, modulename, targetdir, entrypointname, defines={}): assert database.standalone @@ -184,6 +201,10 @@ # gen_readable_parts_of_main_c_file(f, database, preimplementationlines) + # 3) start-up code + print >> f + gen_startupcode(f, database) + f.close() return filename @@ -302,6 +323,8 @@ print >> f, '/***********************************************************/' print >> f, '/*** Module initialization function ***/' print >> f + gen_startupcode(f, database) + print >> f print >> f, 'MODULE_INITFUNC(%s)' % modulename print >> f, '{' print >> f, '\tSETUP_MODULE(%s);' % modulename Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Aug 23 17:55:27 2005 @@ -346,6 +346,9 @@ lines[-1] += ';' return lines + def startupcode(self): + return [] + def getlength(self): return 1 @@ -553,7 +556,7 @@ raise ValueError, "don't know how to generate code for %r" % (fnobj,) -class OpaqueNode(ContainerNode): +class RuntimeTypeInfo_OpaqueNode(ContainerNode): globalcontainer = True includes = () @@ -574,6 +577,34 @@ return [] +class ExtType_OpaqueNode(ContainerNode): + + def enum_dependencies(self): + return [] + + def initializationexpr(self, decoration=''): + yield 'RPyOpaque_INITEXPR_%s' % (self.T.tag,) + + def startupcode(self): + args = [self.ptrname] + # XXX how to make this code more generic? + if self.T.tag == 'ThreadLock': + lock = self.obj.externalobj + if lock.locked(): + args.append('1') + else: + args.append('0') + yield 'RPyOpaque_SETUP_%s(%s);' % (self.T.tag, ', '.join(args)) + + +def opaquenode_factory(db, T, obj): + if T == RuntimeTypeInfo: + return RuntimeTypeInfo_OpaqueNode(db, T, obj) + if hasattr(T, '_exttypeinfo'): + return ExtType_OpaqueNode(db, T, obj) + raise Exception("don't know about %r" % (T,)) + + class PyObjectNode(ContainerNode): globalcontainer = True typename = 'PyObject @' @@ -601,12 +632,12 @@ return [] -ContainerNodeClass = { +ContainerNodeFactory = { Struct: StructNode, GcStruct: StructNode, Array: ArrayNode, GcArray: ArrayNode, FuncType: FuncNode, - OpaqueType: OpaqueNode, + OpaqueType: opaquenode_factory, PyObjectType: PyObjectNode, } Modified: pypy/dist/pypy/translator/c/src/ll_thread.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_thread.h (original) +++ pypy/dist/pypy/translator/c/src/ll_thread.h Tue Aug 23 17:55:27 2005 @@ -50,3 +50,9 @@ { return RPyThreadGetIdent(); } + +#define RPyOpaque_SETUP_ThreadLock(lock, initially_locked) \ + if (!RPyThreadLockInit(lock)) \ + error = "Thread lock init error"; \ + else if ((initially_locked) && !RPyThreadAcquireLock(lock, 1)) \ + error = "Cannot acquire thread lock at init"; Modified: pypy/dist/pypy/translator/c/src/main.h ============================================================================== --- pypy/dist/pypy/translator/c/src/main.h (original) +++ pypy/dist/pypy/translator/c/src/main.h Tue Aug 23 17:55:27 2005 @@ -1,14 +1,26 @@ #define STANDALONE_ENTRY_POINT PYPY_STANDALONE +char *RPython_StartupCode(void); /* forward */ + + int main(int argc, char *argv[]) { + char *errmsg = "out of memory"; int i; RPyListOfString *list = RPyListOfString_New(argc); + if (RPyExceptionOccurred()) goto error; for (i=0; i Author: nik Date: Tue Aug 23 17:55:36 2005 New Revision: 16303 Added: pypy/dist/lib-python/modified-2.4.1/test/test_unpack.py - copied, changed from r16289, pypy/dist/lib-python/2.4.1/test/test_unpack.py Log: changed doctest to expect a pypy-specific exception message. test_unpack now passes. From tismer at codespeak.net Tue Aug 23 18:03:23 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 18:03:23 +0200 (CEST) Subject: [pypy-svn] r16306 - pypy/dist/pypy/objspace/std Message-ID: <20050823160323.0CE4627B3D@code1.codespeak.net> Author: tismer Date: Tue Aug 23 18:03:22 2005 New Revision: 16306 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py Log: reverted this change. unwrap was used somewhere else Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Tue Aug 23 18:03:22 2005 @@ -21,10 +21,10 @@ """ representation for debugging purposes """ return "%s(%r)" % (w_self.__class__.__name__, w_self._value) -## def unwrap(w_self): -## # For faked functions taking unicodearguments. -## # Remove when we no longer need faking. -## return u''.join(w_self._value) + def unwrap(w_self): + # For faked functions taking unicodearguments. + # Remove when we no longer need faking. + return u''.join(w_self._value) registerimplementation(W_UnicodeObject) From ale at codespeak.net Tue Aug 23 18:08:49 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 23 Aug 2005 18:08:49 +0200 (CEST) Subject: [pypy-svn] r16307 - pypy/dist/pypy/objspace/std Message-ID: <20050823160849.9D6B127B3D@code1.codespeak.net> Author: ale Date: Tue Aug 23 18:08:48 2005 New Revision: 16307 Modified: pypy/dist/pypy/objspace/std/iterobject.py Log: dont use unwrap Modified: pypy/dist/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/iterobject.py (original) +++ pypy/dist/pypy/objspace/std/iterobject.py Tue Aug 23 18:08:48 2005 @@ -22,10 +22,7 @@ W_Object.__init__(w_self, space) w_self.w_seq = w_seq w_self.w_len = space.len(w_seq) - if index < 0: - w_self.index = space.unwrap(w_self.w_len) + index - else: - w_self.index = space.unwrap(w_self.w_len) + w_self.index = space.int_w(w_self.w_len) + index registerimplementation(W_SeqIterObject) From ludal at codespeak.net Tue Aug 23 18:25:34 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 18:25:34 +0200 (CEST) Subject: [pypy-svn] r16308 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20050823162534.DE56A27B3D@code1.codespeak.net> Author: ludal Date: Tue Aug 23 18:25:33 2005 New Revision: 16308 Modified: pypy/dist/pypy/interpreter/astcompiler/misc.py pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Log: some more rpython transformation of astcompiler Modified: pypy/dist/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/misc.py Tue Aug 23 18:25:33 2005 @@ -1,9 +1,10 @@ -import types + +from pypy.interpreter.astcompiler import ast def flatten(tup): elts = [] for elt in tup: - if type(elt) == types.TupleType: + if type(elt) == tuple: elts = elts + flatten(elt) else: elts.append(elt) @@ -70,5 +71,6 @@ worklist = [tree] while worklist: node = worklist.pop(0) + assert isinstance(node, ast.Node) node.filename = filename worklist.extend(node.getChildNodes()) Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Tue Aug 23 18:25:33 2005 @@ -5,6 +5,7 @@ import sys import types +from pypy.interpreter.pycode import PyCode from pypy.interpreter.astcompiler import misc, ast from pypy.interpreter.astcompiler.consts \ import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS @@ -220,17 +221,27 @@ order.append(b) return order +class BlockCounter: + def __init__(self): + self._count = 0 + + def inc(self): + self._count += 1 + + def value(self): + return self._count + class Block: - _count = 0 + _count = BlockCounter() def __init__(self, label=''): self.insts = [] self.inEdges = misc.Set() self.outEdges = misc.Set() self.label = label - self.bid = Block._count + self.bid = Block._count.value() self.next = [] - Block._count = Block._count + 1 + Block._count.inc() def __repr__(self): if self.label: @@ -239,7 +250,7 @@ return "" % (self.bid) def __str__(self): - insts = map(str, self.insts) + insts = [ str(i) for i in self.insts ] return "" % (self.label, self.bid, '\n'.join(insts)) @@ -260,7 +271,7 @@ def addNext(self, block): self.next.append(block) - assert len(self.next) == 1, map(str, self.next) + assert len(self.next) == 1, [ str(i) for i in self.next ] _uncond_transfer = ('RETURN_VALUE', 'RAISE_VARARGS', 'YIELD_VALUE', 'JUMP_ABSOLUTE', 'JUMP_FORWARD', 'CONTINUE_LOOP') @@ -642,12 +653,14 @@ argcount = self.argcount if self.flags & CO_VARKEYWORDS: argcount = argcount - 1 - return new.code(argcount, nlocals, self.stacksize, self.flags, - self.lnotab.getCode(), self.getConsts(), - tuple(self.names), tuple(self.varnames), - self.filename, self.name, self.lnotab.firstline, - self.lnotab.getTable(), tuple(self.freevars), - tuple(self.cellvars)) + # was return new.code, now we just return the parameters and let + # the caller create the code object + return (argcount, nlocals, self.stacksize, self.flags, + self.lnotab.getCode(), self.getConsts(), + tuple(self.names), tuple(self.varnames), + self.filename, self.name, self.lnotab.firstline, + self.lnotab.getTable(), tuple(self.freevars), + tuple(self.cellvars)) def getConsts(self): """Return a tuple for the const slot of the code object @@ -754,11 +767,55 @@ return ''.join(self.code) def getTable(self): - return ''.join(map(chr, self.lnotab)) + return ''.join( [ chr(i) for i in self.lnotab ] ) + + +def depth_UNPACK_SEQUENCE(count): + return count-1 +def depth_BUILD_TUPLE(count): + return -count+1 +def depth_BUILD_LIST(count): + return -count+1 +def depth_CALL_FUNCTION(argc): + hi, lo = divmod(argc, 256) + return -(lo + hi * 2) +def depth_CALL_FUNCTION_VAR(argc): + return depth_CALL_FUNCTION(argc)-1 +def depth_CALL_FUNCTION_KW(argc): + return depth_CALL_FUNCTION(argc)-1 +def depth_CALL_FUNCTION_VAR_KW(argc): + return depth_CALL_FUNCTION(argc)-2 +def depth_MAKE_FUNCTION(argc): + return -argc +def depth_MAKE_CLOSURE(argc): + # XXX need to account for free variables too! + return -argc +def depth_BUILD_SLICE(argc): + if argc == 2: + return -1 + elif argc == 3: + return -2 +def depth_DUP_TOPX(argc): + return argc + +DEPTH_OP_TRACKER = { + "UNPACK_SEQUENCE" : depth_UNPACK_SEQUENCE, + "BUILD_TUPLE" : depth_BUILD_TUPLE, + "BUILD_LIST" : depth_BUILD_LIST, + "CALL_FUNCTION" : depth_CALL_FUNCTION, + "CALL_FUNCTION_VAR" : depth_CALL_FUNCTION_VAR, + "CALL_FUNCTION_KW" : depth_CALL_FUNCTION_KW, + "CALL_FUNCTION_VAR_KW" : depth_CALL_FUNCTION_VAR_KW, + "MAKE_FUNCTION" : depth_MAKE_FUNCTION, + "MAKE_CLOSURE" : depth_MAKE_CLOSURE, + "BUILD_SLICE" : depth_BUILD_SLICE, + "DUP_TOPX" : depth_DUP_TOPX, + } class StackDepthTracker: # XXX 1. need to keep track of stack depth on jumps # XXX 2. at least partly as a result, this code is broken + # XXX 3. Don't need a class here! def findDepth(self, insts, debug=0): depth = 0 @@ -779,7 +836,7 @@ break # if we still haven't found a match if delta is None: - meth = getattr(self, opname, None) + meth = DEPTH_OP_TRACKER.get( opname, None ) if meth is not None: depth = depth + meth(i[1]) if depth > maxDepth: @@ -832,32 +889,5 @@ ('LOAD_', 1), ] - def UNPACK_SEQUENCE(self, count): - return count-1 - def BUILD_TUPLE(self, count): - return -count+1 - def BUILD_LIST(self, count): - return -count+1 - def CALL_FUNCTION(self, argc): - hi, lo = divmod(argc, 256) - return -(lo + hi * 2) - def CALL_FUNCTION_VAR(self, argc): - return self.CALL_FUNCTION(argc)-1 - def CALL_FUNCTION_KW(self, argc): - return self.CALL_FUNCTION(argc)-1 - def CALL_FUNCTION_VAR_KW(self, argc): - return self.CALL_FUNCTION(argc)-2 - def MAKE_FUNCTION(self, argc): - return -argc - def MAKE_CLOSURE(self, argc): - # XXX need to account for free variables too! - return -argc - def BUILD_SLICE(self, argc): - if argc == 2: - return -1 - elif argc == 3: - return -2 - def DUP_TOPX(self, argc): - return argc findDepth = StackDepthTracker().findDepth Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Aug 23 18:25:33 2005 @@ -193,7 +193,6 @@ self.locals = misc.Stack() self.setups = misc.Stack() self.last_lineno = None - self._setupGraphDelegation() self._div_op = "BINARY_DIVIDE" # XXX set flags based on future features @@ -216,13 +215,26 @@ intro = "Bad class construction for %s" % self.__class__.__name__ raise AssertionError, intro - def _setupGraphDelegation(self): - self.emit = self.graph.emit - self.newBlock = self.graph.newBlock - self.startBlock = self.graph.startBlock - self.nextBlock = self.graph.nextBlock - self.setDocstring = self.graph.setDocstring + def emit(self, *inst ): + self.graph.emit( *inst ) + + def nextBlock(self, block=None ): + """graph delegation""" + self.graph.newBlock( block ) + + def startBlock(self, block ): + """graph delegation""" + self.graph.startBlock( block ) + + def newBlock(self): + """graph delegation""" + self.graph.newBlock() + + def setDocstring(self, doc): + """graph delegation""" + self.graph.setDocstring( doc ) + def getCode(self): """Return a code object""" return self.graph.getCode() @@ -307,7 +319,7 @@ and a consistent policy implemented and documented. Until then, this method works around missing line numbers. """ - lineno = getattr(node, 'lineno', None) + lineno = node.lineno if lineno is not None and (lineno != self.last_lineno or force): self.emit('SET_LINENO', lineno) @@ -1412,7 +1424,7 @@ walk(node, v, verbose=0) return v.op -class OpFinder: +class OpFinder(ast.ASTVisitor): def __init__(self): self.op = None def visitAssName(self, node): From ludal at codespeak.net Tue Aug 23 18:26:53 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 18:26:53 +0200 (CEST) Subject: [pypy-svn] r16309 - in pypy/dist/pypy/interpreter: . pyparser/test Message-ID: <20050823162653.6EB8A27B3D@code1.codespeak.net> Author: ludal Date: Tue Aug 23 18:26:52 2005 New Revision: 16309 Modified: pypy/dist/pypy/interpreter/pycode.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Log: added a method to create new code objects from parameters Modified: pypy/dist/pypy/interpreter/pycode.py ============================================================================== --- pypy/dist/pypy/interpreter/pycode.py (original) +++ pypy/dist/pypy/interpreter/pycode.py Tue Aug 23 18:26:52 2005 @@ -101,55 +101,79 @@ self.co_lnotab = "" # string: encoding addr<->lineno mapping self.hidden_applevel = False - def _from_code(self, code, hidden_applevel=False): - """ Initialize the code object from a real (CPython) one. - This is just a hack, until we have our own compile. - At the moment, we just fake this. - This method is called by our compile builtin function. - """ - self.hidden_applevel = hidden_applevel - import types - assert isinstance(code, types.CodeType) + + def _code_new( self, argcount, nlocals, stacksize, flags, + code, consts, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars, + hidden_applevel=False): + """Initialize a new code objects from parameters from new.code""" # simply try to suck in all attributes we know of # with a lot of boring asserts to enforce type knowledge # XXX get rid of that ASAP with a real compiler! - x = code.co_argcount; assert isinstance(x, int) + import types + x = argcount; assert isinstance(x, int) self.co_argcount = x - x = code.co_nlocals; assert isinstance(x, int) + x = nlocals; assert isinstance(x, int) self.co_nlocals = x - x = code.co_stacksize; assert isinstance(x, int) + x = stacksize; assert isinstance(x, int) self.co_stacksize = x - x = code.co_flags; assert isinstance(x, int) + x = flags; assert isinstance(x, int) self.co_flags = x - x = code.co_code; assert isinstance(x, str) + x = code; assert isinstance(x, str) self.co_code = x #self.co_consts = - x = code.co_names; assert isinstance(x, tuple) + x = names; assert isinstance(x, tuple) self.co_names = [ str(n) for n in x ] - x = code.co_varnames; assert isinstance(x, tuple) + x = varnames; assert isinstance(x, tuple) self.co_varnames = [ str(n) for n in x ] - x = code.co_freevars; assert isinstance(x, tuple) + x = freevars; assert isinstance(x, tuple) self.co_freevars = [ str(n) for n in x ] - x = code.co_cellvars; assert isinstance(x, tuple) + x = cellvars; assert isinstance(x, tuple) self.co_cellvars = [ str(n) for n in x ] - x = code.co_filename; assert isinstance(x, str) + x = filename; assert isinstance(x, str) self.co_filename = x - x = code.co_name; assert isinstance(x, str) + x = name; assert isinstance(x, str) self.co_name = x - x = code.co_firstlineno; assert isinstance(x, int) + x = firstlineno; assert isinstance(x, int) self.co_firstlineno = x - x = code.co_lnotab; assert isinstance(x, str) + x = lnotab; assert isinstance(x, str) self.co_lnotab = x # recursively _from_code()-ify the code objects in code.co_consts space = self.space newconsts_w = [] - for const in code.co_consts: + for const in consts: if isinstance(const, types.CodeType): const = PyCode(space)._from_code(const, hidden_applevel=hidden_applevel) newconsts_w.append(space.wrap(const)) self.co_consts_w = newconsts_w return self + def _from_code(self, code, hidden_applevel=False): + """ Initialize the code object from a real (CPython) one. + This is just a hack, until we have our own compile. + At the moment, we just fake this. + This method is called by our compile builtin function. + """ + self.hidden_applevel = hidden_applevel + import types + assert isinstance(code, types.CodeType) + self._code_new( code.co_argcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + code.co_name, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + hidden_applevel ) + return self + def create_frame(self, space, w_globals, closure=None): "Create an empty PyFrame suitable for this code object." # select the appropriate kind of frame @@ -235,6 +259,8 @@ W_Root, str, str, int, str, W_Root, W_Root] + + def descr_code__new__(space, w_subtype, argcount, nlocals, stacksize, flags, codestring, w_constants, w_names, Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 18:26:52 2005 @@ -345,7 +345,23 @@ raise OperationError(space.w_TypeError,space.wrap(str(e))) # __________ end of XXX above from pypy.interpreter.pycode import PyCode - return PyCode(space)._from_code(c) + code = PyCode(space) + code._code_new( c[0], + c[1], + c[2], + c[3], + c[4], + c[5], + c[6], + c[7], + c[8], + c[9], + c[10], + c[11], + c[12], + c[13], + ) + return code #compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Tue Aug 23 18:26:52 2005 @@ -38,11 +38,12 @@ assert code1.co_code == code2.co_code def check_compile( expr ): + import new ast_tree = ast_parse_expr( expr ) misc.set_filename("", ast_tree) print ast_tree codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) - code1 = codegenerator.getCode() + code1 = new.code(*codegenerator.getCode()) code2 = ast_compile( expr ) compare_code(code1,code2) From ac at codespeak.net Tue Aug 23 18:27:06 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 23 Aug 2005 18:27:06 +0200 (CEST) Subject: [pypy-svn] r16310 - pypy/dist/lib-python Message-ID: <20050823162706.583E327B3D@code1.codespeak.net> Author: ac Date: Tue Aug 23 18:27:06 2005 New Revision: 16310 Modified: pypy/dist/lib-python/conftest.py Log: MimeWriter is not core. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Aug 23 18:27:06 2005 @@ -545,7 +545,7 @@ RegrTest('test_mhlib.py', enabled=True), RegrTest('test_mimetools.py', enabled=True), RegrTest('test_mimetypes.py', enabled=True), - RegrTest('test_MimeWriter.py', enabled=True, core=True), + RegrTest('test_MimeWriter.py', enabled=True, core=False), RegrTest('test_minidom.py', enabled=False, dumbtest=1), RegrTest('test_mmap.py', enabled=False), RegrTest('test_module.py', enabled=True, dumbtest=1, core=True), From tismer at codespeak.net Tue Aug 23 18:30:53 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 18:30:53 +0200 (CEST) Subject: [pypy-svn] r16311 - pypy/dist/pypy/interpreter Message-ID: <20050823163053.8441B27B3D@code1.codespeak.net> Author: tismer Date: Tue Aug 23 18:30:52 2005 New Revision: 16311 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: had to avoid debug_print at runtime Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 18:30:52 2005 @@ -252,12 +252,21 @@ from _stablecompiler import apphook return apphook.fakeapplevelcompile ''') + self.w_printmessage = self.space.appexec([], r'''(): + def printmessage(msg): + print msg + return printmessage + ''') + def printmessage(self, msg): + space = self.space + space.call_function(self.w_printmessage, space.wrap(msg)) def _get_compiler(self, mode): from pypy.interpreter.error import debug_print import os if os.path.exists('fakecompiler.py') and mode != 'single': - debug_print("faking compiler, because fakecompiler.py is in the current dir") + self.printmessage("faking compiler, because fakecompiler.py" + " is in the current dir") return self.w_compilefake else: return self.w_compileapp From pedronis at codespeak.net Tue Aug 23 18:33:18 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 23 Aug 2005 18:33:18 +0200 (CEST) Subject: [pypy-svn] r16312 - pypy/dist/pypy/translator/c Message-ID: <20050823163318.B8EA827B3D@code1.codespeak.net> Author: pedronis Date: Tue Aug 23 18:33:15 2005 New Revision: 16312 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/node.py Log: more moving refcounting out (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Aug 23 18:33:15 2005 @@ -120,6 +120,7 @@ else: raise Exception("don't know about %r" % (obj,)) + """ def cincrefstmt(self, expr, T): if isinstance(T, Ptr) and T._needsgc(): if expr == 'NULL': # hum @@ -147,6 +148,7 @@ dealloc, expr) return '' +""" def complete(self): i = 0 Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Aug 23 18:33:15 2005 @@ -1,5 +1,5 @@ from pypy.translator.c.support import cdecl -from pypy.rpython.lltype import typeOf, Ptr, PyObject +from pypy.rpython.lltype import typeOf, Ptr, PyObject, ContainerType from pypy.rpython.lltype import getRuntimeTypeInfo PyObjPtr = Ptr(PyObject) @@ -74,6 +74,21 @@ result.append(decrefstmt) result.append('}') + def generic_dealloc(self, expr, T): + db = self.db + if isinstance(T, Ptr) and T._needsgc(): + line = self.pop_alive(expr, T) + if line: + yield line + elif isinstance(T, ContainerType): + defnode = db.gettypedefnode(T) + from pypy.translator.c.node import ExtTypeOpaqueDefNode + if isinstance(defnode, ExtTypeOpaqueDefNode): + yield 'RPyOpaqueDealloc_%s(&(%s));' % (defnode.T.tag, expr) + else: + for line in defnode.visitor_lines(expr, self.generic_dealloc): + yield line + def gcheader_field_name(self, defnode): return 'refcount' @@ -89,6 +104,12 @@ def common_gcheader_initializationexpr(self, defnode): yield 'REFCOUNT_IMMORTAL,' + def deallocator_lines(self, defnode, prefix): + for line in defnode.visitor_lines(prefix, self.generic_dealloc): + yield line + + + # for structs def prepare_nested_gcstruct(self, structdefnode, INNER): @@ -118,7 +139,7 @@ gcinfo.rtti_query_funcptr_argtype = db.gettype(T) else: # is a deallocator really needed, or would it be empty? - if list(structdefnode.deallocator_lines('')): + if list(self.deallocator_lines(structdefnode, '')): gcinfo.static_deallocator = gcinfo.deallocator else: gcinfo.deallocator = None @@ -127,15 +148,36 @@ struct_after_definition = common_after_definition - def struct_implentationcode(self, structdefnode): - pass + def struct_implementationcode(self, structdefnode): + if structdefnode.gcinfo: + gcinfo = structdefnode.gcinfo + if gcinfo.static_deallocator: + yield 'void %s(struct %s *p) {' % (gcinfo.static_deallocator, + structdefnode.name) + for line in self.deallocator_lines(structdefnode, '(*p)'): + yield '\t' + line + yield '\tOP_FREE(p);' + yield '}' + if gcinfo.deallocator and gcinfo.deallocator != gcinfo.static_deallocator: + yield 'void %s(struct %s *p) {' % (gcinfo.deallocator, structdefnode.name) + yield '\tvoid (*staticdealloc) (void *);' + # the refcount should be 0; temporarily bump it to 1 + yield '\tp->%s = 1;' % (structdefnode.gcheader,) + # cast 'p' to the type expected by the rtti_query function + yield '\tstaticdealloc = %s((%s) p);' % ( + gcinfo.rtti_query_funcptr, + cdecl(gcinfo.rtti_query_funcptr_argtype, '')) + yield '\tif (!--p->%s)' % (structdefnode.gcheader,) + yield '\t\tstaticdealloc(p);' + yield '}' + struct_gcheader_initialitionexpr = common_gcheader_initializationexpr # for arrays def array_setup(self, arraydefnode): - if arraydefnode.gcheader and list(arraydefnode.deallocator_lines('')): + if arraydefnode.gcheader and list(self.deallocator_lines(arraydefnode, '')): gcinfo = arraydefnode.gcinfo = RefcountingInfo() gcinfo.deallocator = self.db.namespace.uniquename('dealloc_'+arraydefnode.barename) @@ -144,7 +186,14 @@ array_after_definition = common_after_definition def array_implementationcode(self, arraydefnode): - pass + if arraydefnode.gcinfo: + gcinfo = arraydefnode.gcinfo + if gcinfo.deallocator: + yield 'void %s(struct %s *a) {' % (gcinfo.deallocator, arraydefnode.name) + for line in self.deallocator_lines(arraydefnode, '(*a)'): + yield '\t' + line + yield '\tOP_FREE(a);' + yield '}' array_gcheader_initialitionexpr = common_gcheader_initializationexpr Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Aug 23 18:33:15 2005 @@ -114,40 +114,16 @@ for line in gcpolicy.struct_after_definition(self): yield line - elif phase == 2: # xxx -> gc - if self.gcinfo: - gcinfo = self.gcinfo - if gcinfo.static_deallocator: - yield 'void %s(struct %s *p) {' % (gcinfo.static_deallocator, - self.name) - for line in self.visitor_lines('(*p)', generic_dealloc): - yield '\t' + line - yield '\tOP_FREE(p);' - yield '}' - if gcinfo.deallocator and gcinfo.deallocator != gcinfo.static_deallocator: - yield 'void %s(struct %s *p) {' % (gcinfo.deallocator, self.name) - yield '\tvoid (*staticdealloc) (void *);' - # the refcount should be 0; temporarily bump it to 1 - yield '\tp->%s = 1;' % (self.gcheader,) - # cast 'p' to the type expected by the rtti_query function - yield '\tstaticdealloc = %s((%s) p);' % ( - gcinfo.rtti_query_funcptr, - cdecl(gcinfo.rtti_query_funcptr_argtype, '')) - yield '\tif (!--p->%s)' % (self.gcheader,) - yield '\t\tstaticdealloc(p);' - yield '}' - - def deallocator_lines(self, prefix): - for line in self.visitor_lines(prefix, generic_dealloc): - yield line + elif phase == 2: + for line in gcpolicy.struct_implementationcode(self): + yield line def visitor_lines(self, prefix, on_field): STRUCT = self.STRUCT for name in STRUCT._names: FIELD_T = self.c_struct_field_type(name) cname = self.c_struct_field_name(name) - for line in on_field(self.db, - '%s.%s' % (prefix, cname), + for line in on_field('%s.%s' % (prefix, cname), FIELD_T): yield line @@ -223,18 +199,8 @@ yield line elif phase == 2: - if self.gcinfo: # xxx -> gc - gcinfo = self.gcinfo - if gcinfo.deallocator: - yield 'void %s(struct %s *a) {' % (gcinfo.deallocator, self.name) - for line in self.visitor_lines('(*a)', generic_dealloc): - yield '\t' + line - yield '\tOP_FREE(a);' - yield '}' - - def deallocator_lines(self, prefix): - for line in self.visitor_lines(prefix, generic_dealloc): - yield line + for line in gcpolicy.array_implementationcode(self): + yield line def visitor_lines(self, prefix, on_item): ARRAY = self.ARRAY @@ -245,7 +211,7 @@ while prefix.find(varname) >= 0: i += 1 varname = 'p%d' % i - body = list(on_item(self.db, '(*%s)' % varname, ARRAY.OF)) + body = list(on_item('(*%s)' % varname, ARRAY.OF)) if body: yield '{' yield '\t%s = %s.items;' % (cdecl(self.itemtypename, '*' + varname), @@ -287,20 +253,6 @@ def definition(self, phase): return [] - -def generic_dealloc(db, expr, T): # xxx -> gc, refactor PyObjPtr case - if isinstance(T, Ptr) and T._needsgc(): - line = db.cdecrefstmt(expr, T) - if line: - yield line - elif isinstance(T, ContainerType): - defnode = db.gettypedefnode(T) - if isinstance(defnode, ExtTypeOpaqueDefNode): - yield 'RPyOpaqueDealloc_%s(&(%s));' % (defnode.T.tag, expr) - else: - for line in defnode.visitor_lines(expr, generic_dealloc): - yield line - # ____________________________________________________________ @@ -555,7 +507,7 @@ else: raise ValueError, "don't know how to generate code for %r" % (fnobj,) - +# xxx move it completly to the gcpolicy class RuntimeTypeInfo_OpaqueNode(ContainerNode): globalcontainer = True includes = () From tismer at codespeak.net Tue Aug 23 18:46:31 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 18:46:31 +0200 (CEST) Subject: [pypy-svn] r16313 - pypy/dist/pypy/interpreter Message-ID: <20050823164631.C380327B3D@code1.codespeak.net> Author: tismer Date: Tue Aug 23 18:46:30 2005 New Revision: 16313 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: indentation error caused a method to vanish :-( Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Tue Aug 23 18:46:30 2005 @@ -257,9 +257,10 @@ print msg return printmessage ''') - def printmessage(self, msg): - space = self.space - space.call_function(self.w_printmessage, space.wrap(msg)) + + def printmessage(self, msg): + space = self.space + space.call_function(self.w_printmessage, space.wrap(msg)) def _get_compiler(self, mode): from pypy.interpreter.error import debug_print From ac at codespeak.net Tue Aug 23 18:55:28 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 23 Aug 2005 18:55:28 +0200 (CEST) Subject: [pypy-svn] r16314 - in pypy/dist/pypy: interpreter/astcompiler interpreter/stablecompiler lib/_stablecompiler module/recparser/compiler Message-ID: <20050823165528.B16D327B3D@code1.codespeak.net> Author: ac Date: Tue Aug 23 18:55:28 2005 New Revision: 16314 Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/lib/_stablecompiler/pycodegen.py pypy/dist/pypy/module/recparser/compiler/pycodegen.py Log: Change errormessage to match that of CPython. Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Aug 23 18:55:28 2005 @@ -524,7 +524,7 @@ self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not allowed inside 'finally' clause (%s, %d)" + msg = "'continue' not supported inside 'finally' clause (%s, %d)" raise SyntaxError, msg % (node.filename, node.lineno) def visitTest(self, node, jump): Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Tue Aug 23 18:55:28 2005 @@ -528,7 +528,7 @@ self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not allowed inside 'finally' clause (%s, %d)" + msg = "'continue' not supported inside 'finally' clause (%s, %d)" raise SyntaxError, msg % (node.filename, node.lineno) def visitTest(self, node, jump): Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Tue Aug 23 18:55:28 2005 @@ -529,7 +529,7 @@ self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not allowed inside 'finally' clause (%s, %d)" + msg = "'continue' not supported inside 'finally' clause (%s, %d)" raise SyntaxError, msg % (node.filename, node.lineno) def visitTest(self, node, jump): Modified: pypy/dist/pypy/module/recparser/compiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/module/recparser/compiler/pycodegen.py (original) +++ pypy/dist/pypy/module/recparser/compiler/pycodegen.py Tue Aug 23 18:55:28 2005 @@ -525,7 +525,7 @@ self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not allowed inside 'finally' clause (%s, %d)" + msg = "'continue' not supported inside 'finally' clause (%s, %d)" raise SyntaxError, msg % (node.filename, node.lineno) def visitTest(self, node, jump): From pedronis at codespeak.net Tue Aug 23 19:00:26 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 23 Aug 2005 19:00:26 +0200 (CEST) Subject: [pypy-svn] r16315 - pypy/dist/pypy/translator/c Message-ID: <20050823170026.9D5E627B3D@code1.codespeak.net> Author: pedronis Date: Tue Aug 23 19:00:25 2005 New Revision: 16315 Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/gc.py Log: finished factoring out refcounting logic into RefcountingPolicy in gc.py: delegating malloc implementation (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Tue Aug 23 19:00:25 2005 @@ -475,12 +475,10 @@ TYPE = self.lltypemap(op.result).TO typename = self.db.gettype(TYPE) eresult = self.expr(op.result) - result = ['OP_ZERO_MALLOC(sizeof(%s), %s, %s);' % (cdecl(typename, ''), - eresult, - err), - '%s->%s = 0;' % (eresult, # xxx the incref is generically done on the results - self.db.gettypedefnode(TYPE).gcheader), - ] + esize = 'sizeof(%s)' % cdecl(typename, '') + + result = list(self.db.gcpolicy.zero_malloc(TYPE, esize, eresult, err)) + return '\t'.join(result) def OP_MALLOC_VARSIZE(self, op, err): @@ -491,25 +489,24 @@ if isinstance(TYPE, Struct): arfld = TYPE._arrayfld lenfld = "%s.length" % nodedef.c_struct_field_name(arfld) - TYPE = TYPE._flds[TYPE._arrayfld] - assert isinstance(TYPE, Array) - itemtypename = self.db.gettype(TYPE.OF) + VARPART = TYPE._flds[TYPE._arrayfld] + else: + VARPART = TYPE + assert isinstance(VARPART, Array) + itemtypename = self.db.gettype(VARPART.OF) elength = self.expr(op.args[1]) eresult = self.expr(op.result) - if TYPE.OF == Void: # strange - size = 'sizeof(%s)' % (cdecl(typename, ''),) + if VARPART.OF == Void: # strange + esize = 'sizeof(%s)' % (cdecl(typename, ''),) else: - size = 'sizeof(%s)+((%s-1)*sizeof(%s))' % (cdecl(typename, ''), + esize = 'sizeof(%s)+((%s-1)*sizeof(%s))' % (cdecl(typename, ''), elength, cdecl(itemtypename, '')) - result = ['OP_ZERO_MALLOC(%s, %s, %s);' % (size, - eresult, - err), + result = list(self.db.gcpolicy.zero_malloc(TYPE, esize, eresult, err)) + result.append( '%s->%s = %s;' % (eresult, lenfld, elength), - '%s->%s = 0;' % (eresult, # xxx the incref is generically done on the results - nodedef.gcheader), - ] + ) return '\t'.join(result) def OP_CAST_POINTER(self, op, err): Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Aug 23 19:00:25 2005 @@ -208,3 +208,10 @@ defnode.name,) node.name = defnode.gcinfo.static_deallocator node.ptrname = '((void (*)(void *)) %s)' % (node.name,) + + # zero malloc impl + + def zero_malloc(self, TYPE, esize, eresult, err): + yield 'OP_ZERO_MALLOC(%s, %s, %s);' % (esize, + eresult, + err) From cfbolz at codespeak.net Tue Aug 23 19:03:00 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 23 Aug 2005 19:03:00 +0200 (CEST) Subject: [pypy-svn] r16316 - pypy/dist/pypy/rpython/memory Message-ID: <20050823170300.3679827B3D@code1.codespeak.net> Author: cfbolz Date: Tue Aug 23 19:02:59 2005 New Revision: 16316 Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py pypy/dist/pypy/rpython/memory/support.py Log: oops, our ints are really longs on C-level. Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypelayout.py (original) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Tue Aug 23 19:02:59 2005 @@ -3,8 +3,8 @@ import struct -primitive_to_fmt = {lltype.Signed: "i", - lltype.Unsigned: "I", +primitive_to_fmt = {lltype.Signed: "l", + lltype.Unsigned: "L", lltype.Char: "c", lltype.Bool: "B", lltype.Float: "d", Modified: pypy/dist/pypy/rpython/memory/support.py ============================================================================== --- pypy/dist/pypy/rpython/memory/support.py (original) +++ pypy/dist/pypy/rpython/memory/support.py Tue Aug 23 19:02:59 2005 @@ -1,8 +1,9 @@ from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL - +from pypy.rpython import lltype +from pypy.rpython.memory.lltypelayout import sizeof import struct -INT_SIZE = struct.calcsize("i") +INT_SIZE = sizeof(lltype.Signed) class AddressLinkedList(object): _alloc_flavor_ = "" From hpk at codespeak.net Tue Aug 23 19:05:51 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 19:05:51 +0200 (CEST) Subject: [pypy-svn] r16317 - pypy/dist/lib-python Message-ID: <20050823170551.286DA27B4B@code1.codespeak.net> Author: hpk Date: Tue Aug 23 19:05:50 2005 New Revision: 16317 Modified: pypy/dist/lib-python/conftest.py Log: (hpk, arigo) consider test_site.py to be an implementation detail we don't import it in PyPy at startup and it doesn't appear to be sensible because we have other means of doing what site.py does for CPython. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Aug 23 19:05:50 2005 @@ -636,7 +636,7 @@ RegrTest('test_shlex.py', enabled=True), RegrTest('test_shutil.py', enabled=True), RegrTest('test_signal.py', enabled=False), - RegrTest('test_site.py', enabled=True, core=True), + RegrTest('test_site.py', enabled=False, core=False), # considered cpython impl-detail # Needs non-faked codecs. RegrTest('test_slice.py', enabled=True, dumbtest=1, core=True), RegrTest('test_socket.py', enabled=False), From ericvrp at codespeak.net Tue Aug 23 19:07:25 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 23 Aug 2005 19:07:25 +0200 (CEST) Subject: [pypy-svn] r16318 - pypy/dist/pypy/translator/goal Message-ID: <20050823170725.9AE4F27B4B@code1.codespeak.net> Author: ericvrp Date: Tue Aug 23 19:07:24 2005 New Revision: 16318 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: always assume -no-o with -llvm is supplied Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Tue Aug 23 19:07:24 2005 @@ -139,7 +139,7 @@ print 'Specializing...' t.specialize(dont_simplify_again=True, crash_on_first_typeerror=not options['-t-insist']) - if not options['-no-o']: + if not options['-no-o'] and not options['-llvm']: print 'Back-end optimizations...' t.backend_optimizations() if a: From ac at codespeak.net Tue Aug 23 19:18:31 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 23 Aug 2005 19:18:31 +0200 (CEST) Subject: [pypy-svn] r16319 - in pypy/dist/pypy: interpreter/astcompiler interpreter/stablecompiler lib/_stablecompiler module/recparser/compiler Message-ID: <20050823171831.E403827B4B@code1.codespeak.net> Author: ac Date: Tue Aug 23 19:18:31 2005 New Revision: 16319 Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/lib/_stablecompiler/pycodegen.py pypy/dist/pypy/module/recparser/compiler/pycodegen.py Log: Adjust errormessages to match what test_exceptions regressiontest expects. Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Aug 23 19:18:31 2005 @@ -502,8 +502,7 @@ def visitContinue(self, node): if not self.setups: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) kind, block = self.setups.top() if kind == LOOP: self.set_lineno(node) @@ -519,13 +518,12 @@ if kind == LOOP: break if kind != LOOP: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not supported inside 'finally' clause (%s, %d)" - raise SyntaxError, msg % (node.filename, node.lineno) + msg = "'continue' not supported inside 'finally' clause" # " (%s, %d)" + raise SyntaxError, msg # % (node.filename, node.lineno) def visitTest(self, node, jump): end = self.newBlock() Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Tue Aug 23 19:18:31 2005 @@ -506,8 +506,7 @@ def visitContinue(self, node): if not self.setups: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) kind, block = self.setups.top() if kind == LOOP: self.set_lineno(node) @@ -523,13 +522,12 @@ if kind == LOOP: break if kind != LOOP: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not supported inside 'finally' clause (%s, %d)" - raise SyntaxError, msg % (node.filename, node.lineno) + msg = "'continue' not supported inside 'finally' clause" # " (%s, %d)" + raise SyntaxError, msg # % (node.filename, node.lineno) def visitTest(self, node, jump): end = self.newBlock() Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Tue Aug 23 19:18:31 2005 @@ -507,8 +507,7 @@ def visitContinue(self, node): if not self.setups: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) kind, block = self.setups.top() if kind == LOOP: self.set_lineno(node) @@ -524,13 +523,12 @@ if kind == LOOP: break if kind != LOOP: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not supported inside 'finally' clause (%s, %d)" - raise SyntaxError, msg % (node.filename, node.lineno) + msg = "'continue' not supported inside 'finally' clause" # " (%s, %d)" + raise SyntaxError, msg # % (node.filename, node.lineno) def visitTest(self, node, jump): end = self.newBlock() Modified: pypy/dist/pypy/module/recparser/compiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/module/recparser/compiler/pycodegen.py (original) +++ pypy/dist/pypy/module/recparser/compiler/pycodegen.py Tue Aug 23 19:18:31 2005 @@ -503,8 +503,7 @@ def visitContinue(self, node): if not self.setups: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) kind, block = self.setups.top() if kind == LOOP: self.set_lineno(node) @@ -520,13 +519,12 @@ if kind == LOOP: break if kind != LOOP: - raise SyntaxError, "'continue' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) self.emit('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: - msg = "'continue' not supported inside 'finally' clause (%s, %d)" - raise SyntaxError, msg % (node.filename, node.lineno) + msg = "'continue' not supported inside 'finally' clause" # " (%s, %d)" + raise SyntaxError, msg # % (node.filename, node.lineno) def visitTest(self, node, jump): end = self.newBlock() From nik at codespeak.net Tue Aug 23 19:26:50 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 19:26:50 +0200 (CEST) Subject: [pypy-svn] r16321 - pypy/dist/pypy/module/_sre Message-ID: <20050823172650.1760427B3F@code1.codespeak.net> Author: nik Date: Tue Aug 23 19:26:49 2005 New Revision: 16321 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: some more typedef trickery for W_State that hopefully makes specialization succeed. Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Tue Aug 23 19:26:49 2005 @@ -2,6 +2,7 @@ # XXX is it allowed to import app-level module like this? from pypy.module._sre.app_info import CODESIZE from pypy.interpreter.typedef import GetSetProperty, TypeDef +from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app import sys @@ -55,7 +56,7 @@ self.marks = [] self.lastindex = -1 self.marks_stack = [] - self.context_stack = self.space.newlist([]) + self.w_context_stack = self.space.newlist([]) self.w_repeat = self.space.w_None def set_mark(self, w_mark_nr, w_position): @@ -104,27 +105,39 @@ def lower(self, w_char_ord): return getlower(self.space, w_char_ord, self.space.wrap(self.flags)) +def interp_attrproperty_int(name, cls): + "NOT_RPYTHON: initialization-time only" + def fget(space, obj): + return space.wrap(getattr(obj, name)) + def fset(space, obj, w_value): + return setattr(obj, name, space.int_w(w_value)) + return GetSetProperty(fget, fset, cls=cls) + +def interp_attrproperty_obj_w(name, cls): + "NOT_RPYTHON: initialization-time only" + def fget(space, obj): + return getattr(obj, name) + def fset(space, obj, w_value): + return setattr(state, name, w_value) + return GetSetProperty(fget, fset, cls=cls) + W_State.typedef = TypeDef("W_State", - string = GetSetProperty(lambda space, state: state.w_string, - lambda space, state, value: setattr(state, "w_string", value)), - start = GetSetProperty(lambda space, state: space.wrap(state.start), - lambda space, state, value: setattr(state, "start", space.int_w(value))), - end = GetSetProperty(lambda space, state: space.wrap(state.end)), - string_position = GetSetProperty(lambda space, state: space.wrap(state.string_position), - lambda space, state, value: setattr(state, "string_position", space.int_w(value))), - pos = GetSetProperty(lambda space, state: space.wrap(state.pos)), - lastindex = GetSetProperty(lambda space, state: space.wrap(state.lastindex)), - context_stack = GetSetProperty(lambda space, state: state.context_stack), - repeat = GetSetProperty(lambda space, state: state.w_repeat, - lambda space, state, value: setattr(state, "w_repeat", value)), - reset = interp2app(W_State.reset, unwrap_spec = ["self"]), + string = interp_attrproperty_obj_w("w_string", W_State), + start = interp_attrproperty_int("start", W_State), + end = interp_attrproperty_int("end", W_State), + string_position = interp_attrproperty_int("string_position", W_State), + pos = interp_attrproperty("pos", W_State), + lastindex = interp_attrproperty("lastindex", W_State), + context_stack = interp_attrproperty_w("w_context_stack", W_State), + repeat = interp_attrproperty_obj_w("w_repeat", W_State), + reset = interp2app(W_State.reset), set_mark = interp2app(W_State.set_mark), get_marks = interp2app(W_State.get_marks), create_regs = interp2app(W_State.create_regs), - marks_push = interp2app(W_State.marks_push, unwrap_spec = ["self"]), - marks_pop = interp2app(W_State.marks_pop, unwrap_spec = ["self"]), - marks_pop_keep = interp2app(W_State.marks_pop_keep, unwrap_spec = ["self"]), - marks_pop_discard = interp2app(W_State.marks_pop_discard, unwrap_spec = ["self"]), + marks_push = interp2app(W_State.marks_push), + marks_pop = interp2app(W_State.marks_pop), + marks_pop_keep = interp2app(W_State.marks_pop_keep), + marks_pop_discard = interp2app(W_State.marks_pop_discard), lower = interp2app(W_State.lower), ) From arigo at codespeak.net Tue Aug 23 19:27:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 19:27:12 +0200 (CEST) Subject: [pypy-svn] r16322 - pypy/dist/pypy/module/thread/test Message-ID: <20050823172712.6804A27B41@code1.codespeak.net> Author: arigo Date: Tue Aug 23 19:27:11 2005 New Revision: 16322 Modified: pypy/dist/pypy/module/thread/test/test_local.py Log: Fixed broken thread test: it contained a race condition if two __init__ calls were occurring in parallel. Modified: pypy/dist/pypy/module/thread/test/test_local.py ============================================================================== --- pypy/dist/pypy/module/thread/test/test_local.py (original) +++ pypy/dist/pypy/module/thread/test/test_local.py Tue Aug 23 19:27:11 2005 @@ -48,26 +48,22 @@ def test_local_init(self): import thread - feedback = [] - seen = {} + tags = [1, 2, 3, 4, 5, 54321] + seen = [] class X(thread._local): def __init__(self, n): assert n == 42 - self.tag = len(feedback) - feedback.append(1) + self.tag = tags.pop() x = X(42) - assert x.tag == 0 - assert feedback == [1] + assert x.tag == 54321 def f(): - seen[x.tag] = True + seen.append(x.tag) for i in range(5): thread.start_new_thread(f, ()) self.waitfor(lambda: len(seen) == 5, timeout=20.0) - assert seen == {1: True, - 2: True, - 3: True, - 4: True, - 5: True} - assert len(feedback) == 6 + seen1 = seen[:] + seen1.sort() + assert seen1 == [1, 2, 3, 4, 5] + assert tags == [] From arigo at codespeak.net Tue Aug 23 19:30:32 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 19:30:32 +0200 (CEST) Subject: [pypy-svn] r16323 - pypy/dist/pypy/module/thread Message-ID: <20050823173032.7B29127B3F@code1.codespeak.net> Author: arigo Date: Tue Aug 23 19:30:31 2005 New Revision: 16323 Modified: pypy/dist/pypy/module/thread/os_local.py pypy/dist/pypy/module/thread/threadlocals.py Log: Needs to import exttable wherever thread.*() functions can be called. Modified: pypy/dist/pypy/module/thread/os_local.py ============================================================================== --- pypy/dist/pypy/module/thread/os_local.py (original) +++ pypy/dist/pypy/module/thread/os_local.py Tue Aug 23 19:30:31 2005 @@ -5,6 +5,9 @@ from pypy.interpreter.typedef import descr_set_dict from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments +# Force the declaration of thread.start_new_thread() & co. for RPython +import pypy.module.thread.rpython.exttable + class Local(Wrappable): """Thread-local data""" Modified: pypy/dist/pypy/module/thread/threadlocals.py ============================================================================== --- pypy/dist/pypy/module/thread/threadlocals.py (original) +++ pypy/dist/pypy/module/thread/threadlocals.py Tue Aug 23 19:30:31 2005 @@ -1,5 +1,8 @@ import thread +# Force the declaration of thread.start_new_thread() & co. for RPython +import pypy.module.thread.rpython.exttable + class OSThreadLocals: """Thread-local storage for OS-level threads. From hpk at codespeak.net Tue Aug 23 19:38:08 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 19:38:08 +0200 (CEST) Subject: [pypy-svn] r16325 - pypy/dist/lib-python Message-ID: <20050823173808.B0EFE27B3F@code1.codespeak.net> Author: hpk Date: Tue Aug 23 19:38:07 2005 New Revision: 16325 Modified: pypy/dist/lib-python/conftest.py Log: - specify usemodules=STRING (whitespace-separated) instead of a list - make thread tests use 'thread' module Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Aug 23 19:38:07 2005 @@ -271,7 +271,7 @@ """ Regression Test Declaration.""" def __init__(self, basename, enabled=False, dumbtest=False, oldstyle=False, core=False, uselibfile=False, - usemodules = None): + usemodules = ''): self.basename = basename self.enabled = enabled self.dumbtest = dumbtest @@ -280,9 +280,7 @@ # line options haven't been parsed! self._oldstyle = oldstyle self._uselibfile = uselibfile - if usemodules is None: - usemodules = [] - self._usemodules = usemodules + self._usemodules = usemodules.split() self.core = core def oldstyle(self): @@ -302,7 +300,7 @@ for name in 'oldstyle', 'core', 'uselibfile': if getattr(self, name): l.append(name) - for name in self.usemodules: + for name in self.usemodules: l.append(name) return l @@ -540,7 +538,7 @@ RegrTest('test_macpath.py', enabled=True), RegrTest('test_mailbox.py', enabled=True), RegrTest('test_marshal.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_math.py', enabled=True, core=True, usemodules=['math']), + RegrTest('test_math.py', enabled=True, core=True, usemodules='math'), RegrTest('test_md5.py', enabled=False), RegrTest('test_mhlib.py', enabled=True), RegrTest('test_mimetools.py', enabled=True), @@ -679,15 +677,15 @@ #rev 10840: Uncaught interp-level exception: Same place as test_cfgparser RegrTest('test_textwrap.py', enabled=True), - RegrTest('test_thread.py', enabled=True, core=True), - RegrTest('test_threaded_import.py', enabled=True, core=True), - RegrTest('test_threadedtempfile.py', enabled=True, core=True), + RegrTest('test_thread.py', enabled=True, usemodules="thread", core=True), + RegrTest('test_threaded_import.py', usemodules="thread", enabled=True, core=True), + RegrTest('test_threadedtempfile.py', usemodules="thread", enabled=True, core=True), #rev 10840: ImportError: thread - RegrTest('test_threading.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_threading.py', usemodules="thread", enabled=True, dumbtest=1, core=True), #rev 10840: ImportError: thread - RegrTest('test_threading_local.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_threadsignals.py', enabled=False, dumbtest=1), + RegrTest('test_threading_local.py', usemodules="thread", enabled=True, dumbtest=1, core=True), + RegrTest('test_threadsignals.py', usemodules="thread", enabled=False, dumbtest=1), RegrTest('test_time.py', enabled=True, core=True), RegrTest('test_timeout.py', enabled=False), From nik at codespeak.net Tue Aug 23 19:45:02 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 19:45:02 +0200 (CEST) Subject: [pypy-svn] r16326 - pypy/dist/lib-python Message-ID: <20050823174502.2C8AA27B3F@code1.codespeak.net> Author: nik Date: Tue Aug 23 19:44:57 2005 New Revision: 16326 Modified: pypy/dist/lib-python/failure_list.txt Log: examined test_traceback failure. cannot be fixed immediately. Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Tue Aug 23 19:44:57 2005 @@ -88,3 +88,7 @@ test_multibytecodec needs the gb18030 codec, part of the CJK codecs. either remove this test from core or maybe fake or reimplement the CJK codecs? + +test_traceback + test_nocaret fails because the examined SyntaxError doesn't carry a + line number From nik at codespeak.net Tue Aug 23 19:48:54 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Tue, 23 Aug 2005 19:48:54 +0200 (CEST) Subject: [pypy-svn] r16327 - pypy/dist/pypy/module/_sre Message-ID: <20050823174854.7769327B3F@code1.codespeak.net> Author: nik Date: Tue Aug 23 19:48:53 2005 New Revision: 16327 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: typo Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Tue Aug 23 19:48:53 2005 @@ -118,7 +118,7 @@ def fget(space, obj): return getattr(obj, name) def fset(space, obj, w_value): - return setattr(state, name, w_value) + return setattr(obj, name, w_value) return GetSetProperty(fget, fset, cls=cls) W_State.typedef = TypeDef("W_State", From arigo at codespeak.net Tue Aug 23 19:53:00 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 23 Aug 2005 19:53:00 +0200 (CEST) Subject: [pypy-svn] r16328 - in pypy/dist/pypy/module/thread: . test Message-ID: <20050823175300.EAF6827B3F@code1.codespeak.net> Author: arigo Date: Tue Aug 23 19:52:59 2005 New Revision: 16328 Modified: pypy/dist/pypy/module/thread/os_local.py pypy/dist/pypy/module/thread/test/test_local.py Log: Missing import. Added a test for this and for __dict__ access of thread._local objects in general. Modified: pypy/dist/pypy/module/thread/os_local.py ============================================================================== --- pypy/dist/pypy/module/thread/os_local.py (original) +++ pypy/dist/pypy/module/thread/os_local.py Tue Aug 23 19:52:59 2005 @@ -1,4 +1,5 @@ import thread +from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef, interp2app from pypy.interpreter.typedef import GetSetProperty, descr_get_dict Modified: pypy/dist/pypy/module/thread/test/test_local.py ============================================================================== --- pypy/dist/pypy/module/thread/test/test_local.py (original) +++ pypy/dist/pypy/module/thread/test/test_local.py Tue Aug 23 19:52:59 2005 @@ -67,3 +67,20 @@ seen1.sort() assert seen1 == [1, 2, 3, 4, 5] assert tags == [] + + def test_local_setdict(self): + import thread + x = thread._local() + raises(TypeError, "x.__dict__ = 42") + done = [] + def f(n): + x.spam = n + assert x.__dict__["spam"] == n + x.__dict__ = {"bar": n+1} + assert x.bar == n+1 + assert not hasattr(x, "spam") + done.append(1) + for i in range(5): + thread.start_new_thread(f, (i,)) + self.waitfor(lambda: len(done) == 5, timeout=20.0) + assert len(done) == 5 From hpk at codespeak.net Tue Aug 23 19:54:45 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 19:54:45 +0200 (CEST) Subject: [pypy-svn] r16329 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20050823175445.ACC5527B3F@code1.codespeak.net> Author: hpk Date: Tue Aug 23 19:54:45 2005 New Revision: 16329 Modified: pypy/dist/pypy/module/__builtin__/compiling.py pypy/dist/pypy/module/__builtin__/test/test_builtin.py Log: allow explicit Nones to eval() (new in python 2.4) Modified: pypy/dist/pypy/module/__builtin__/compiling.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/compiling.py (original) +++ pypy/dist/pypy/module/__builtin__/compiling.py Tue Aug 23 19:54:45 2005 @@ -69,7 +69,7 @@ except IndexError: caller = None - if w_globals is None: + if w_globals is None or space.is_w(w_globals, space.w_None): if caller is None: w_globals = w_locals = space.newdict([]) else: Modified: pypy/dist/pypy/module/__builtin__/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_builtin.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_builtin.py Tue Aug 23 19:54:45 2005 @@ -336,6 +336,10 @@ assert eval(" \t1+2\n") == 3 assert eval("len([])") == 0 assert eval("len([])", {}) == 0 + # cpython 2.4 allows this (raises in 2.3) + assert eval("3", None, None) == 3 + i = 4 + assert eval("i", None, None) == 4 def test_compile(self): co = compile('1+2', '?', 'eval') From ludal at codespeak.net Tue Aug 23 19:58:19 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Tue, 23 Aug 2005 19:58:19 +0200 (CEST) Subject: [pypy-svn] r16332 - in pypy/dist/pypy/interpreter: astcompiler pyparser pyparser/test Message-ID: <20050823175819.2F97527B3F@code1.codespeak.net> Author: ludal Date: Tue Aug 23 19:58:15 2005 New Revision: 16332 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/ast.txt pypy/dist/pypy/interpreter/astcompiler/astgen.py pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/astcompiler/symbols.py pypy/dist/pypy/interpreter/astcompiler/visitor.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Log: - get rid of the $*$@@#!! visitor pattern used in the compiler module - add to compile test all the tests from test_astbuilder - bug fixes of the compiler to make those test pass Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Tue Aug 23 19:58:15 2005 @@ -2,7 +2,7 @@ This file is automatically generated by Tools/compiler/astgen.py """ -from consts import CO_VARARGS, CO_VARKEYWORDS +from consts import CO_VARARGS, CO_VARKEYWORDS, OP_ASSIGN def flatten(list): l = [] @@ -34,7 +34,7 @@ return self.getChildren() def getChildNodes(self): return [] # implemented by subclasses - def visit(self, visitor, *args): + def accept(self, visitor, *args): return visitor.visitNode(self, *args) def flatten(self): res = [] @@ -47,7 +47,7 @@ return res class EmptyNode(Node): - def visit(self, visitor, *args): + def accept(self, visitor, *args): return visitor.visitEmptyNode(self, *args) class Expression(Node): @@ -66,7 +66,7 @@ def __repr__(self): return "Expression(%s)" % (repr(self.node)) - def visit(self, visitor, *args): + def accept(self, visitor, *args): return visitor.visitExpression(self, *args) class Add(Node): @@ -84,8 +84,8 @@ def __repr__(self): return "Add((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitAdd(self, args) + def accept(self, visitor, *args): + return visitor.visitAdd(self, *args) class And(Node): def __init__(self, nodes, lineno=None): @@ -103,8 +103,8 @@ def __repr__(self): return "And(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitAnd(self, args) + def accept(self, visitor, *args): + return visitor.visitAnd(self, *args) class AssAttr(Node): def __init__(self, expr, attrname, flags, lineno=None): @@ -122,8 +122,8 @@ def __repr__(self): return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) - def accept(self, visitor, args): - return visitor.visitAssAttr(self, args) + def accept(self, visitor, *args): + return visitor.visitAssAttr(self, *args) class AssList(Node): def __init__(self, nodes, lineno=None): @@ -141,8 +141,8 @@ def __repr__(self): return "AssList(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitAssList(self, args) + def accept(self, visitor, *args): + return visitor.visitAssList(self, *args) class AssName(Node): def __init__(self, name, flags, lineno=None): @@ -159,8 +159,8 @@ def __repr__(self): return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) - def accept(self, visitor, args): - return visitor.visitAssName(self, args) + def accept(self, visitor, *args): + return visitor.visitAssName(self, *args) class AssTuple(Node): def __init__(self, nodes, lineno=None): @@ -178,8 +178,8 @@ def __repr__(self): return "AssTuple(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitAssTuple(self, args) + def accept(self, visitor, *args): + return visitor.visitAssTuple(self, *args) class Assert(Node): def __init__(self, test, fail, lineno=None): @@ -203,8 +203,8 @@ def __repr__(self): return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) - def accept(self, visitor, args): - return visitor.visitAssert(self, args) + def accept(self, visitor, *args): + return visitor.visitAssert(self, *args) class Assign(Node): def __init__(self, nodes, expr, lineno=None): @@ -227,8 +227,8 @@ def __repr__(self): return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) - def accept(self, visitor, args): - return visitor.visitAssign(self, args) + def accept(self, visitor, *args): + return visitor.visitAssign(self, *args) class AugAssign(Node): def __init__(self, node, op, expr, lineno=None): @@ -246,8 +246,8 @@ def __repr__(self): return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) - def accept(self, visitor, args): - return visitor.visitAugAssign(self, args) + def accept(self, visitor, *args): + return visitor.visitAugAssign(self, *args) class Backquote(Node): def __init__(self, expr, lineno=None): @@ -263,8 +263,8 @@ def __repr__(self): return "Backquote(%s)" % (repr(self.expr),) - def accept(self, visitor, args): - return visitor.visitBackquote(self, args) + def accept(self, visitor, *args): + return visitor.visitBackquote(self, *args) class Bitand(Node): def __init__(self, nodes, lineno=None): @@ -282,8 +282,8 @@ def __repr__(self): return "Bitand(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitBitand(self, args) + def accept(self, visitor, *args): + return visitor.visitBitand(self, *args) class Bitor(Node): def __init__(self, nodes, lineno=None): @@ -301,8 +301,8 @@ def __repr__(self): return "Bitor(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitBitor(self, args) + def accept(self, visitor, *args): + return visitor.visitBitor(self, *args) class Bitxor(Node): def __init__(self, nodes, lineno=None): @@ -320,8 +320,8 @@ def __repr__(self): return "Bitxor(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitBitxor(self, args) + def accept(self, visitor, *args): + return visitor.visitBitxor(self, *args) class Break(Node): def __init__(self, lineno=None): @@ -336,8 +336,8 @@ def __repr__(self): return "Break()" - def accept(self, visitor, args): - return visitor.visitBreak(self, args) + def accept(self, visitor, *args): + return visitor.visitBreak(self, *args) class CallFunc(Node): def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None): @@ -368,8 +368,8 @@ def __repr__(self): return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) - def accept(self, visitor, args): - return visitor.visitCallFunc(self, args) + def accept(self, visitor, *args): + return visitor.visitCallFunc(self, *args) class Class(Node): def __init__(self, name, bases, doc, code, lineno=None): @@ -396,8 +396,8 @@ def __repr__(self): return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code)) - def accept(self, visitor, args): - return visitor.visitClass(self, args) + def accept(self, visitor, *args): + return visitor.visitClass(self, *args) class Compare(Node): def __init__(self, expr, ops, lineno=None): @@ -420,8 +420,8 @@ def __repr__(self): return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) - def accept(self, visitor, args): - return visitor.visitCompare(self, args) + def accept(self, visitor, *args): + return visitor.visitCompare(self, *args) class Const(Node): def __init__(self, value, lineno=None): @@ -437,8 +437,8 @@ def __repr__(self): return "Const(%s)" % (repr(self.value),) - def accept(self, visitor, args): - return visitor.visitConst(self, args) + def accept(self, visitor, *args): + return visitor.visitConst(self, *args) class Continue(Node): def __init__(self, lineno=None): @@ -453,8 +453,8 @@ def __repr__(self): return "Continue()" - def accept(self, visitor, args): - return visitor.visitContinue(self, args) + def accept(self, visitor, *args): + return visitor.visitContinue(self, *args) class Decorators(Node): def __init__(self, nodes, lineno=None): @@ -472,8 +472,8 @@ def __repr__(self): return "Decorators(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitDecorators(self, args) + def accept(self, visitor, *args): + return visitor.visitDecorators(self, *args) class Dict(Node): def __init__(self, items, lineno=None): @@ -491,8 +491,8 @@ def __repr__(self): return "Dict(%s)" % (repr(self.items),) - def accept(self, visitor, args): - return visitor.visitDict(self, args) + def accept(self, visitor, *args): + return visitor.visitDict(self, *args) class Discard(Node): def __init__(self, expr, lineno=None): @@ -508,8 +508,8 @@ def __repr__(self): return "Discard(%s)" % (repr(self.expr),) - def accept(self, visitor, args): - return visitor.visitDiscard(self, args) + def accept(self, visitor, *args): + return visitor.visitDiscard(self, *args) class Div(Node): def __init__(self, (left, right), lineno=None): @@ -526,8 +526,8 @@ def __repr__(self): return "Div((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitDiv(self, args) + def accept(self, visitor, *args): + return visitor.visitDiv(self, *args) class Ellipsis(Node): def __init__(self, lineno=None): @@ -542,8 +542,8 @@ def __repr__(self): return "Ellipsis()" - def accept(self, visitor, args): - return visitor.visitEllipsis(self, args) + def accept(self, visitor, *args): + return visitor.visitEllipsis(self, *args) class Exec(Node): def __init__(self, expr, locals, globals, lineno=None): @@ -571,8 +571,8 @@ def __repr__(self): return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) - def accept(self, visitor, args): - return visitor.visitExec(self, args) + def accept(self, visitor, *args): + return visitor.visitExec(self, *args) class FloorDiv(Node): def __init__(self, (left, right), lineno=None): @@ -589,8 +589,8 @@ def __repr__(self): return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitFloorDiv(self, args) + def accept(self, visitor, *args): + return visitor.visitFloorDiv(self, *args) class For(Node): def __init__(self, assign, list, body, else_, lineno=None): @@ -620,8 +620,8 @@ def __repr__(self): return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) - def accept(self, visitor, args): - return visitor.visitFor(self, args) + def accept(self, visitor, *args): + return visitor.visitFor(self, *args) class From(Node): def __init__(self, modname, names, lineno=None): @@ -638,8 +638,8 @@ def __repr__(self): return "From(%s, %s)" % (repr(self.modname), repr(self.names)) - def accept(self, visitor, args): - return visitor.visitFrom(self, args) + def accept(self, visitor, *args): + return visitor.visitFrom(self, *args) class Function(Node): def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None): @@ -681,14 +681,14 @@ def __repr__(self): return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) - def accept(self, visitor, args): - return visitor.visitFunction(self, args) + def accept(self, visitor, *args): + return visitor.visitFunction(self, *args) class GenExpr(Node): def __init__(self, code, lineno=None): Node.__init__(self, lineno) self.code = code - self.argnames = ['[outmost-iterable]'] + self.argnames = [AssName('[outmost-iterable]', OP_ASSIGN)] self.varargs = self.kwargs = None @@ -702,8 +702,8 @@ def __repr__(self): return "GenExpr(%s)" % (repr(self.code),) - def accept(self, visitor, args): - return visitor.visitGenExpr(self, args) + def accept(self, visitor, *args): + return visitor.visitGenExpr(self, *args) class GenExprFor(Node): def __init__(self, assign, iter, ifs, lineno=None): @@ -731,8 +731,8 @@ def __repr__(self): return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) - def accept(self, visitor, args): - return visitor.visitGenExprFor(self, args) + def accept(self, visitor, *args): + return visitor.visitGenExprFor(self, *args) class GenExprIf(Node): def __init__(self, test, lineno=None): @@ -748,8 +748,8 @@ def __repr__(self): return "GenExprIf(%s)" % (repr(self.test),) - def accept(self, visitor, args): - return visitor.visitGenExprIf(self, args) + def accept(self, visitor, *args): + return visitor.visitGenExprIf(self, *args) class GenExprInner(Node): def __init__(self, expr, quals, lineno=None): @@ -772,8 +772,8 @@ def __repr__(self): return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) - def accept(self, visitor, args): - return visitor.visitGenExprInner(self, args) + def accept(self, visitor, *args): + return visitor.visitGenExprInner(self, *args) class Getattr(Node): def __init__(self, expr, attrname, lineno=None): @@ -790,8 +790,8 @@ def __repr__(self): return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) - def accept(self, visitor, args): - return visitor.visitGetattr(self, args) + def accept(self, visitor, *args): + return visitor.visitGetattr(self, *args) class Global(Node): def __init__(self, names, lineno=None): @@ -807,8 +807,8 @@ def __repr__(self): return "Global(%s)" % (repr(self.names),) - def accept(self, visitor, args): - return visitor.visitGlobal(self, args) + def accept(self, visitor, *args): + return visitor.visitGlobal(self, *args) class If(Node): def __init__(self, tests, else_, lineno=None): @@ -832,8 +832,8 @@ def __repr__(self): return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) - def accept(self, visitor, args): - return visitor.visitIf(self, args) + def accept(self, visitor, *args): + return visitor.visitIf(self, *args) class Import(Node): def __init__(self, names, lineno=None): @@ -849,8 +849,8 @@ def __repr__(self): return "Import(%s)" % (repr(self.names),) - def accept(self, visitor, args): - return visitor.visitImport(self, args) + def accept(self, visitor, *args): + return visitor.visitImport(self, *args) class Invert(Node): def __init__(self, expr, lineno=None): @@ -866,8 +866,8 @@ def __repr__(self): return "Invert(%s)" % (repr(self.expr),) - def accept(self, visitor, args): - return visitor.visitInvert(self, args) + def accept(self, visitor, *args): + return visitor.visitInvert(self, *args) class Keyword(Node): def __init__(self, name, expr, lineno=None): @@ -884,8 +884,8 @@ def __repr__(self): return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) - def accept(self, visitor, args): - return visitor.visitKeyword(self, args) + def accept(self, visitor, *args): + return visitor.visitKeyword(self, *args) class Lambda(Node): def __init__(self, argnames, defaults, flags, code, lineno=None): @@ -919,8 +919,8 @@ def __repr__(self): return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) - def accept(self, visitor, args): - return visitor.visitLambda(self, args) + def accept(self, visitor, *args): + return visitor.visitLambda(self, *args) class LeftShift(Node): def __init__(self, (left, right), lineno=None): @@ -937,8 +937,8 @@ def __repr__(self): return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitLeftShift(self, args) + def accept(self, visitor, *args): + return visitor.visitLeftShift(self, *args) class List(Node): def __init__(self, nodes, lineno=None): @@ -956,8 +956,8 @@ def __repr__(self): return "List(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitList(self, args) + def accept(self, visitor, *args): + return visitor.visitList(self, *args) class ListComp(Node): def __init__(self, expr, quals, lineno=None): @@ -980,8 +980,8 @@ def __repr__(self): return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) - def accept(self, visitor, args): - return visitor.visitListComp(self, args) + def accept(self, visitor, *args): + return visitor.visitListComp(self, *args) class ListCompFor(Node): def __init__(self, assign, list, ifs, lineno=None): @@ -1007,8 +1007,8 @@ def __repr__(self): return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) - def accept(self, visitor, args): - return visitor.visitListCompFor(self, args) + def accept(self, visitor, *args): + return visitor.visitListCompFor(self, *args) class ListCompIf(Node): def __init__(self, test, lineno=None): @@ -1024,8 +1024,8 @@ def __repr__(self): return "ListCompIf(%s)" % (repr(self.test),) - def accept(self, visitor, args): - return visitor.visitListCompIf(self, args) + def accept(self, visitor, *args): + return visitor.visitListCompIf(self, *args) class Mod(Node): def __init__(self, (left, right), lineno=None): @@ -1042,8 +1042,8 @@ def __repr__(self): return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitMod(self, args) + def accept(self, visitor, *args): + return visitor.visitMod(self, *args) class Module(Node): def __init__(self, doc, node, lineno=None): @@ -1060,8 +1060,8 @@ def __repr__(self): return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) - def accept(self, visitor, args): - return visitor.visitModule(self, args) + def accept(self, visitor, *args): + return visitor.visitModule(self, *args) class Mul(Node): def __init__(self, (left, right), lineno=None): @@ -1078,8 +1078,8 @@ def __repr__(self): return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitMul(self, args) + def accept(self, visitor, *args): + return visitor.visitMul(self, *args) class Name(Node): def __init__(self, varname, lineno=None): @@ -1095,8 +1095,24 @@ def __repr__(self): return "Name(%s)" % (repr(self.varname),) - def accept(self, visitor, args): - return visitor.visitName(self, args) + def accept(self, visitor, *args): + return visitor.visitName(self, *args) + +class NoneConst(Node): + def __init__(self, lineno=None): + Node.__init__(self, lineno) + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "NoneConst()" + + def accept(self, visitor, *args): + return visitor.visitNoneConst(self, *args) class Not(Node): def __init__(self, expr, lineno=None): @@ -1112,8 +1128,25 @@ def __repr__(self): return "Not(%s)" % (repr(self.expr),) - def accept(self, visitor, args): - return visitor.visitNot(self, args) + def accept(self, visitor, *args): + return visitor.visitNot(self, *args) + +class NumberConst(Node): + def __init__(self, number_value, lineno=None): + Node.__init__(self, lineno) + self.number_value = number_value + + def getChildren(self): + return self.number_value, + + def getChildNodes(self): + return [] + + def __repr__(self): + return "NumberConst(%s)" % (repr(self.number_value),) + + def accept(self, visitor, *args): + return visitor.visitNumberConst(self, *args) class Or(Node): def __init__(self, nodes, lineno=None): @@ -1131,8 +1164,8 @@ def __repr__(self): return "Or(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitOr(self, args) + def accept(self, visitor, *args): + return visitor.visitOr(self, *args) class Pass(Node): def __init__(self, lineno=None): @@ -1147,8 +1180,8 @@ def __repr__(self): return "Pass()" - def accept(self, visitor, args): - return visitor.visitPass(self, args) + def accept(self, visitor, *args): + return visitor.visitPass(self, *args) class Power(Node): def __init__(self, (left, right), lineno=None): @@ -1165,8 +1198,8 @@ def __repr__(self): return "Power((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitPower(self, args) + def accept(self, visitor, *args): + return visitor.visitPower(self, *args) class Print(Node): def __init__(self, nodes, dest, lineno=None): @@ -1190,8 +1223,8 @@ def __repr__(self): return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) - def accept(self, visitor, args): - return visitor.visitPrint(self, args) + def accept(self, visitor, *args): + return visitor.visitPrint(self, *args) class Printnl(Node): def __init__(self, nodes, dest, lineno=None): @@ -1215,8 +1248,8 @@ def __repr__(self): return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) - def accept(self, visitor, args): - return visitor.visitPrintnl(self, args) + def accept(self, visitor, *args): + return visitor.visitPrintnl(self, *args) class Raise(Node): def __init__(self, expr1, expr2, expr3, lineno=None): @@ -1245,8 +1278,8 @@ def __repr__(self): return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) - def accept(self, visitor, args): - return visitor.visitRaise(self, args) + def accept(self, visitor, *args): + return visitor.visitRaise(self, *args) class Return(Node): def __init__(self, value, lineno=None): @@ -1262,8 +1295,8 @@ def __repr__(self): return "Return(%s)" % (repr(self.value),) - def accept(self, visitor, args): - return visitor.visitReturn(self, args) + def accept(self, visitor, *args): + return visitor.visitReturn(self, *args) class RightShift(Node): def __init__(self, (left, right), lineno=None): @@ -1280,8 +1313,8 @@ def __repr__(self): return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitRightShift(self, args) + def accept(self, visitor, *args): + return visitor.visitRightShift(self, *args) class Slice(Node): def __init__(self, expr, flags, lower, upper, lineno=None): @@ -1311,8 +1344,8 @@ def __repr__(self): return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) - def accept(self, visitor, args): - return visitor.visitSlice(self, args) + def accept(self, visitor, *args): + return visitor.visitSlice(self, *args) class Sliceobj(Node): def __init__(self, nodes, lineno=None): @@ -1330,8 +1363,8 @@ def __repr__(self): return "Sliceobj(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitSliceobj(self, args) + def accept(self, visitor, *args): + return visitor.visitSliceobj(self, *args) class Stmt(Node): def __init__(self, nodes, lineno=None): @@ -1349,8 +1382,25 @@ def __repr__(self): return "Stmt(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitStmt(self, args) + def accept(self, visitor, *args): + return visitor.visitStmt(self, *args) + +class StringConst(Node): + def __init__(self, string_value, lineno=None): + Node.__init__(self, lineno) + self.string_value = string_value + + def getChildren(self): + return self.string_value, + + def getChildNodes(self): + return [] + + def __repr__(self): + return "StringConst(%s)" % (repr(self.string_value),) + + def accept(self, visitor, *args): + return visitor.visitStringConst(self, *args) class Sub(Node): def __init__(self, (left, right), lineno=None): @@ -1367,8 +1417,8 @@ def __repr__(self): return "Sub((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, args): - return visitor.visitSub(self, args) + def accept(self, visitor, *args): + return visitor.visitSub(self, *args) class Subscript(Node): def __init__(self, expr, flags, subs, lineno=None): @@ -1393,8 +1443,8 @@ def __repr__(self): return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) - def accept(self, visitor, args): - return visitor.visitSubscript(self, args) + def accept(self, visitor, *args): + return visitor.visitSubscript(self, *args) class TryExcept(Node): def __init__(self, body, handlers, else_, lineno=None): @@ -1421,8 +1471,8 @@ def __repr__(self): return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) - def accept(self, visitor, args): - return visitor.visitTryExcept(self, args) + def accept(self, visitor, *args): + return visitor.visitTryExcept(self, *args) class TryFinally(Node): def __init__(self, body, final, lineno=None): @@ -1439,8 +1489,8 @@ def __repr__(self): return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) - def accept(self, visitor, args): - return visitor.visitTryFinally(self, args) + def accept(self, visitor, *args): + return visitor.visitTryFinally(self, *args) class Tuple(Node): def __init__(self, nodes, lineno=None): @@ -1458,8 +1508,8 @@ def __repr__(self): return "Tuple(%s)" % (repr(self.nodes),) - def accept(self, visitor, args): - return visitor.visitTuple(self, args) + def accept(self, visitor, *args): + return visitor.visitTuple(self, *args) class UnaryAdd(Node): def __init__(self, expr, lineno=None): @@ -1475,8 +1525,8 @@ def __repr__(self): return "UnaryAdd(%s)" % (repr(self.expr),) - def accept(self, visitor, args): - return visitor.visitUnaryAdd(self, args) + def accept(self, visitor, *args): + return visitor.visitUnaryAdd(self, *args) class UnarySub(Node): def __init__(self, expr, lineno=None): @@ -1492,8 +1542,8 @@ def __repr__(self): return "UnarySub(%s)" % (repr(self.expr),) - def accept(self, visitor, args): - return visitor.visitUnarySub(self, args) + def accept(self, visitor, *args): + return visitor.visitUnarySub(self, *args) class While(Node): def __init__(self, test, body, else_, lineno=None): @@ -1520,8 +1570,8 @@ def __repr__(self): return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) - def accept(self, visitor, args): - return visitor.visitWhile(self, args) + def accept(self, visitor, *args): + return visitor.visitWhile(self, *args) class Yield(Node): def __init__(self, value, lineno=None): @@ -1537,8 +1587,8 @@ def __repr__(self): return "Yield(%s)" % (repr(self.value),) - def accept(self, visitor, args): - return visitor.visitYield(self, args) + def accept(self, visitor, *args): + return visitor.visitYield(self, *args) class ASTVisitor(object): @@ -1547,151 +1597,157 @@ It could also use to identify base type for visit arguments of AST nodes """ - def default(self, node, args): + def default(self, node, *args): for child in node.getChildNodes(): - child.visit(self, args) + child.accept(self, *args) - def visitAdd(self, args): - return self.default( args ) - def visitAnd(self, args): - return self.default( args ) - def visitAssAttr(self, args): - return self.default( args ) - def visitAssList(self, args): - return self.default( args ) - def visitAssName(self, args): - return self.default( args ) - def visitAssTuple(self, args): - return self.default( args ) - def visitAssert(self, args): - return self.default( args ) - def visitAssign(self, args): - return self.default( args ) - def visitAugAssign(self, args): - return self.default( args ) - def visitBackquote(self, args): - return self.default( args ) - def visitBitand(self, args): - return self.default( args ) - def visitBitor(self, args): - return self.default( args ) - def visitBitxor(self, args): - return self.default( args ) - def visitBreak(self, args): - return self.default( args ) - def visitCallFunc(self, args): - return self.default( args ) - def visitClass(self, args): - return self.default( args ) - def visitCompare(self, args): - return self.default( args ) - def visitConst(self, args): - return self.default( args ) - def visitContinue(self, args): - return self.default( args ) - def visitDecorators(self, args): - return self.default( args ) - def visitDict(self, args): - return self.default( args ) - def visitDiscard(self, args): - return self.default( args ) - def visitDiv(self, args): - return self.default( args ) - def visitEllipsis(self, args): - return self.default( args ) - def visitExec(self, args): - return self.default( args ) - def visitFloorDiv(self, args): - return self.default( args ) - def visitFor(self, args): - return self.default( args ) - def visitFrom(self, args): - return self.default( args ) - def visitFunction(self, args): - return self.default( args ) - def visitGenExpr(self, args): - return self.default( args ) - def visitGenExprFor(self, args): - return self.default( args ) - def visitGenExprIf(self, args): - return self.default( args ) - def visitGenExprInner(self, args): - return self.default( args ) - def visitGetattr(self, args): - return self.default( args ) - def visitGlobal(self, args): - return self.default( args ) - def visitIf(self, args): - return self.default( args ) - def visitImport(self, args): - return self.default( args ) - def visitInvert(self, args): - return self.default( args ) - def visitKeyword(self, args): - return self.default( args ) - def visitLambda(self, args): - return self.default( args ) - def visitLeftShift(self, args): - return self.default( args ) - def visitList(self, args): - return self.default( args ) - def visitListComp(self, args): - return self.default( args ) - def visitListCompFor(self, args): - return self.default( args ) - def visitListCompIf(self, args): - return self.default( args ) - def visitMod(self, args): - return self.default( args ) - def visitModule(self, args): - return self.default( args ) - def visitMul(self, args): - return self.default( args ) - def visitName(self, args): - return self.default( args ) - def visitNot(self, args): - return self.default( args ) - def visitOr(self, args): - return self.default( args ) - def visitPass(self, args): - return self.default( args ) - def visitPower(self, args): - return self.default( args ) - def visitPrint(self, args): - return self.default( args ) - def visitPrintnl(self, args): - return self.default( args ) - def visitRaise(self, args): - return self.default( args ) - def visitReturn(self, args): - return self.default( args ) - def visitRightShift(self, args): - return self.default( args ) - def visitSlice(self, args): - return self.default( args ) - def visitSliceobj(self, args): - return self.default( args ) - def visitStmt(self, args): - return self.default( args ) - def visitSub(self, args): - return self.default( args ) - def visitSubscript(self, args): - return self.default( args ) - def visitTryExcept(self, args): - return self.default( args ) - def visitTryFinally(self, args): - return self.default( args ) - def visitTuple(self, args): - return self.default( args ) - def visitUnaryAdd(self, args): - return self.default( args ) - def visitUnarySub(self, args): - return self.default( args ) - def visitWhile(self, args): - return self.default( args ) - def visitYield(self, args): - return self.default( args ) + def visitAdd(self, node, *args): + return self.default( node, *args ) + def visitAnd(self, node, *args): + return self.default( node, *args ) + def visitAssAttr(self, node, *args): + return self.default( node, *args ) + def visitAssList(self, node, *args): + return self.default( node, *args ) + def visitAssName(self, node, *args): + return self.default( node, *args ) + def visitAssTuple(self, node, *args): + return self.default( node, *args ) + def visitAssert(self, node, *args): + return self.default( node, *args ) + def visitAssign(self, node, *args): + return self.default( node, *args ) + def visitAugAssign(self, node, *args): + return self.default( node, *args ) + def visitBackquote(self, node, *args): + return self.default( node, *args ) + def visitBitand(self, node, *args): + return self.default( node, *args ) + def visitBitor(self, node, *args): + return self.default( node, *args ) + def visitBitxor(self, node, *args): + return self.default( node, *args ) + def visitBreak(self, node, *args): + return self.default( node, *args ) + def visitCallFunc(self, node, *args): + return self.default( node, *args ) + def visitClass(self, node, *args): + return self.default( node, *args ) + def visitCompare(self, node, *args): + return self.default( node, *args ) + def visitConst(self, node, *args): + return self.default( node, *args ) + def visitContinue(self, node, *args): + return self.default( node, *args ) + def visitDecorators(self, node, *args): + return self.default( node, *args ) + def visitDict(self, node, *args): + return self.default( node, *args ) + def visitDiscard(self, node, *args): + return self.default( node, *args ) + def visitDiv(self, node, *args): + return self.default( node, *args ) + def visitEllipsis(self, node, *args): + return self.default( node, *args ) + def visitExec(self, node, *args): + return self.default( node, *args ) + def visitFloorDiv(self, node, *args): + return self.default( node, *args ) + def visitFor(self, node, *args): + return self.default( node, *args ) + def visitFrom(self, node, *args): + return self.default( node, *args ) + def visitFunction(self, node, *args): + return self.default( node, *args ) + def visitGenExpr(self, node, *args): + return self.default( node, *args ) + def visitGenExprFor(self, node, *args): + return self.default( node, *args ) + def visitGenExprIf(self, node, *args): + return self.default( node, *args ) + def visitGenExprInner(self, node, *args): + return self.default( node, *args ) + def visitGetattr(self, node, *args): + return self.default( node, *args ) + def visitGlobal(self, node, *args): + return self.default( node, *args ) + def visitIf(self, node, *args): + return self.default( node, *args ) + def visitImport(self, node, *args): + return self.default( node, *args ) + def visitInvert(self, node, *args): + return self.default( node, *args ) + def visitKeyword(self, node, *args): + return self.default( node, *args ) + def visitLambda(self, node, *args): + return self.default( node, *args ) + def visitLeftShift(self, node, *args): + return self.default( node, *args ) + def visitList(self, node, *args): + return self.default( node, *args ) + def visitListComp(self, node, *args): + return self.default( node, *args ) + def visitListCompFor(self, node, *args): + return self.default( node, *args ) + def visitListCompIf(self, node, *args): + return self.default( node, *args ) + def visitMod(self, node, *args): + return self.default( node, *args ) + def visitModule(self, node, *args): + return self.default( node, *args ) + def visitMul(self, node, *args): + return self.default( node, *args ) + def visitName(self, node, *args): + return self.default( node, *args ) + def visitNoneConst(self, node, *args): + return self.default( node, *args ) + def visitNot(self, node, *args): + return self.default( node, *args ) + def visitNumberConst(self, node, *args): + return self.default( node, *args ) + def visitOr(self, node, *args): + return self.default( node, *args ) + def visitPass(self, node, *args): + return self.default( node, *args ) + def visitPower(self, node, *args): + return self.default( node, *args ) + def visitPrint(self, node, *args): + return self.default( node, *args ) + def visitPrintnl(self, node, *args): + return self.default( node, *args ) + def visitRaise(self, node, *args): + return self.default( node, *args ) + def visitReturn(self, node, *args): + return self.default( node, *args ) + def visitRightShift(self, node, *args): + return self.default( node, *args ) + def visitSlice(self, node, *args): + return self.default( node, *args ) + def visitSliceobj(self, node, *args): + return self.default( node, *args ) + def visitStmt(self, node, *args): + return self.default( node, *args ) + def visitStringConst(self, node, *args): + return self.default( node, *args ) + def visitSub(self, node, *args): + return self.default( node, *args ) + def visitSubscript(self, node, *args): + return self.default( node, *args ) + def visitTryExcept(self, node, *args): + return self.default( node, *args ) + def visitTryFinally(self, node, *args): + return self.default( node, *args ) + def visitTuple(self, node, *args): + return self.default( node, *args ) + def visitUnaryAdd(self, node, *args): + return self.default( node, *args ) + def visitUnarySub(self, node, *args): + return self.default( node, *args ) + def visitWhile(self, node, *args): + return self.default( node, *args ) + def visitYield(self, node, *args): + return self.default( node, *args ) for name, obj in globals().items(): if isinstance(obj, type) and issubclass(obj, Node): Modified: pypy/dist/pypy/interpreter/astcompiler/ast.txt ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.txt (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.txt Tue Aug 23 19:58:15 2005 @@ -27,6 +27,9 @@ Return: value Yield: value Const: value* +NoneConst: +StringConst: string_value* +NumberConst: number_value* Print: nodes!, dest& Printnl: nodes!, dest& Discard: expr @@ -92,7 +95,7 @@ self.kwargs = 1 init(GenExpr): - self.argnames = ['[outmost-iterable]'] + self.argnames = [AssName('[outmost-iterable]', OP_ASSIGN)] self.varargs = self.kwargs = None init(GenExprFor): Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Tue Aug 23 19:58:15 2005 @@ -192,12 +192,12 @@ print >> buf, ' return "%s()"' % self.name def _gen_visit(self, buf): - print >> buf, " def accept(self, visitor, args):" - print >> buf, " return visitor.visit%s(self, args)" % self.name + print >> buf, " def accept(self, visitor, *args):" + print >> buf, " return visitor.visit%s(self, *args)" % self.name def gen_base_visit(self, buf): - print >> buf, " def visit%s(self, args):" % self.name - print >> buf, " return self.default( args )" + print >> buf, " def visit%s(self, node, *args):" % self.name + print >> buf, " return self.default( node, *args )" rx_init = re.compile('init\((.*)\):') @@ -233,9 +233,9 @@ It could also use to identify base type for visit arguments of AST nodes """ - def default(self, node, args): + def default(self, node, *args): for child in node.getChildNodes(): - child.visit(self, args) + child.accept(self, *args) ''' @@ -265,7 +265,7 @@ This file is automatically generated by Tools/compiler/astgen.py """ -from consts import CO_VARARGS, CO_VARKEYWORDS +from consts import CO_VARARGS, CO_VARKEYWORDS, OP_ASSIGN def flatten(list): l = [] @@ -297,7 +297,7 @@ return self.getChildren() def getChildNodes(self): return [] # implemented by subclasses - def visit(self, visitor, *args): + def accept(self, visitor, *args): return visitor.visitNode(self, *args) def flatten(self): res = [] @@ -310,7 +310,7 @@ return res class EmptyNode(Node): - def visit(self, visitor, *args): + def accept(self, visitor, *args): return visitor.visitEmptyNode(self, *args) class Expression(Node): @@ -329,7 +329,7 @@ def __repr__(self): return "Expression(%s)" % (repr(self.node)) - def visit(self, visitor, *args): + def accept(self, visitor, *args): return visitor.visitExpression(self, *args) ### EPILOGUE Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Tue Aug 23 19:58:15 2005 @@ -25,6 +25,7 @@ print " next", self.current.next print " ", self.current.get_children() print repr(block) + assert block is not None self.current = block def nextBlock(self, block=None): @@ -354,13 +355,19 @@ self.varnames = [] for var in args: if isinstance(var, ast.AssName): - self.varnames.append(var.name) + _name = var.name + assert type(_name) == str + self.varnames.append( _name ) elif isinstance(var, TupleArg): - self.varnames.append(var.getName()) + _name = var.getName() + assert type(_name) == str + self.varnames.append( _name ) elif isinstance(var, ast.AssTuple): for n in var.flatten(): assert isinstance(n, ast.AssName) - self.varnames.append(n.name) + _name = n.name + assert type(_name) == str + self.varnames.append( _name ) self.stage = RAW self.orderedblocks = [] Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Aug 23 19:58:15 2005 @@ -127,7 +127,7 @@ mtime = struct.pack(' 1: end = self.newBlock() @@ -580,16 +580,16 @@ stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): - start, anchor = self.visit(for_) + start, anchor = for_.accept( self ) cont = None for if_ in for_.ifs: if cont is None: cont = self.newBlock() - self.visit(if_, cont) + if_.accept( self, cont) stack.insert(0, (start, cont, anchor)) self._implicitNameOp('LOAD', append) - self.visit(node.expr) + node.expr.accept( self ) self.emit('CALL_FUNCTION', 1) self.emit('POP_TOP') @@ -610,18 +610,18 @@ start = self.newBlock() anchor = self.newBlock() - self.visit(node.list) + node.list.accept( self ) self.emit('GET_ITER') self.nextBlock(start) self.set_lineno(node, force=True) self.emit('FOR_ITER', anchor) self.nextBlock() - self.visit(node.assign) + node.assign.accept( self ) return start, anchor def visitListCompIf(self, node, branch): self.set_lineno(node, force=True) - self.visit(node.test) + node.test.accept( self ) self.emit('JUMP_IF_FALSE', branch) self.newBlock() self.emit('POP_TOP') @@ -643,7 +643,7 @@ self.emit('MAKE_FUNCTION', 0) # precomputation of outmost iterable - self.visit(node.code.quals[0].iter) + node.code.quals[0].iter.accept( self ) self.emit('GET_ITER') self.emit('CALL_FUNCTION', 1) @@ -653,15 +653,15 @@ stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): - start, anchor = self.visit(for_) + start, anchor = for_.accept( self ) cont = None for if_ in for_.ifs: if cont is None: cont = self.newBlock() - self.visit(if_, cont) + if_.accept( self, cont) stack.insert(0, (start, cont, anchor)) - self.visit(node.expr) + node.expr.accept( self ) self.emit('YIELD_VALUE') for start, cont, anchor in stack: @@ -682,19 +682,19 @@ if node.is_outmost: self.loadName('[outmost-iterable]') else: - self.visit(node.iter) + node.iter.accept( self ) self.emit('GET_ITER') self.nextBlock(start) self.set_lineno(node, force=True) self.emit('FOR_ITER', anchor) self.nextBlock() - self.visit(node.assign) + node.assign.accept( self ) return start, anchor def visitGenExprIf(self, node, branch): self.set_lineno(node, force=True) - self.visit(node.test) + node.test.accept( self ) self.emit('JUMP_IF_FALSE', branch) self.newBlock() self.emit('POP_TOP') @@ -711,13 +711,13 @@ # loaded as a global even if there is a local name. I guess this # is a sort of renaming op. self.nextBlock() - self.visit(node.test) + node.test.accept( self ) self.emit('JUMP_IF_TRUE', end) self.nextBlock() self.emit('POP_TOP') self.emit('LOAD_GLOBAL', 'AssertionError') if node.fail: - self.visit(node.fail) + node.fail.accept( self ) self.emit('RAISE_VARARGS', 2) else: self.emit('RAISE_VARARGS', 1) @@ -728,13 +728,13 @@ self.set_lineno(node) n = 0 if node.expr1: - self.visit(node.expr1) + node.expr1.accept( self ) n = n + 1 if node.expr2: - self.visit(node.expr2) + node.expr2.accept( self ) n = n + 1 if node.expr3: - self.visit(node.expr3) + node.expr3.accept( self ) n = n + 1 self.emit('RAISE_VARARGS', n) @@ -750,7 +750,7 @@ self.emit('SETUP_EXCEPT', handlers) self.nextBlock(body) self.setups.push((EXCEPT, body)) - self.visit(node.body) + node.body.accept( self ) self.emit('POP_BLOCK') self.setups.pop() self.emit('JUMP_FORWARD', lElse) @@ -762,7 +762,7 @@ self.set_lineno(expr) if expr: self.emit('DUP_TOP') - self.visit(expr) + expr.accept( self ) self.emit('COMPARE_OP', 'exception match') next = self.newBlock() self.emit('JUMP_IF_FALSE', next) @@ -770,11 +770,11 @@ self.emit('POP_TOP') self.emit('POP_TOP') if target: - self.visit(target) + target.accept( self ) else: self.emit('POP_TOP') self.emit('POP_TOP') - self.visit(body) + body.accept( self ) self.emit('JUMP_FORWARD', end) if expr: self.nextBlock(next) @@ -785,7 +785,7 @@ self.emit('END_FINALLY') if node.else_: self.nextBlock(lElse) - self.visit(node.else_) + node.else_.accept( self ) self.nextBlock(end) def visitTryFinally(self, node): @@ -795,13 +795,13 @@ self.emit('SETUP_FINALLY', final) self.nextBlock(body) self.setups.push((TRY_FINALLY, body)) - self.visit(node.body) + node.body.accept( self ) self.emit('POP_BLOCK') self.setups.pop() self.emit('LOAD_CONST', None) self.nextBlock(final) self.setups.push((END_FINALLY, final)) - self.visit(node.final) + node.final.accept( self ) self.emit('END_FINALLY') self.setups.pop() @@ -809,7 +809,7 @@ def visitDiscard(self, node): self.set_lineno(node) - self.visit(node.expr) + node.expr.accept( self ) self.emit('POP_TOP') def visitConst(self, node): @@ -826,7 +826,7 @@ def visitKeyword(self, node): self.emit('LOAD_CONST', node.name) - self.visit(node.expr) + node.expr.accept( self ) def visitGlobal(self, node): # no code to generate @@ -877,21 +877,21 @@ self.emit('LOAD_ATTR', elt) def visitGetattr(self, node): - self.visit(node.expr) + node.expr.accept( self ) self.emit('LOAD_ATTR', self.mangle(node.attrname)) # next five implement assignments def visitAssign(self, node): self.set_lineno(node) - self.visit(node.expr) + node.expr.accept( self ) dups = len(node.nodes) - 1 for i in range(len(node.nodes)): elt = node.nodes[i] if i < dups: self.emit('DUP_TOP') if isinstance(elt, ast.Node): - self.visit(elt) + elt.accept( self ) def visitAssName(self, node): if node.flags == 'OP_ASSIGN': @@ -903,7 +903,7 @@ print "oops", node.flags def visitAssAttr(self, node): - self.visit(node.expr) + node.expr.accept( self ) if node.flags == 'OP_ASSIGN': self.emit('STORE_ATTR', self.mangle(node.attrname)) elif node.flags == 'OP_DELETE': @@ -916,7 +916,7 @@ if findOp(node) != 'OP_DELETE': self.emit(op, len(node.nodes)) for child in node.nodes: - self.visit(child) + child.accept( self ) if VERSION > 1: visitAssTuple = _visitAssSequence @@ -933,10 +933,10 @@ def visitAugAssign(self, node): self.set_lineno(node) aug_node = wrap_aug(node.node) - self.visit(aug_node, "load") - self.visit(node.expr) + aug_node.accept( self, "load") + node.expr.accept( self ) self.emit(self._augmented_opcode[node.op]) - self.visit(aug_node, "store") + aug_node.accept( self, "store") _augmented_opcode = { '+=' : 'INPLACE_ADD', @@ -961,7 +961,7 @@ def visitAugGetattr(self, node, mode): if mode == "load": - self.visit(node.expr) + node.expr.accept( self ) self.emit('DUP_TOP') self.emit('LOAD_ATTR', self.mangle(node.attrname)) elif mode == "store": @@ -995,32 +995,32 @@ self.emit('STORE_SUBSCR') def visitExec(self, node): - self.visit(node.expr) + node.expr.accept( self ) if node.locals is None: self.emit('LOAD_CONST', None) else: - self.visit(node.locals) + node.locals.accept( self ) if node.globals is None: self.emit('DUP_TOP') else: - self.visit(node.globals) + node.globals.accept( self ) self.emit('EXEC_STMT') def visitCallFunc(self, node): pos = 0 kw = 0 self.set_lineno(node) - self.visit(node.node) + node.node.accept( self ) for arg in node.args: - self.visit(arg) + arg.accept( self ) if isinstance(arg, ast.Keyword): kw = kw + 1 else: pos = pos + 1 if node.star_args is not None: - self.visit(node.star_args) + node.star_args.accept( self ) if node.dstar_args is not None: - self.visit(node.dstar_args) + node.dstar_args.accept( self ) have_star = node.star_args is not None have_dstar = node.dstar_args is not None opcode = callfunc_opcode_info[have_star, have_dstar] @@ -1029,11 +1029,11 @@ def visitPrint(self, node, newline=0): self.set_lineno(node) if node.dest: - self.visit(node.dest) + node.dest.accept( self ) for child in node.nodes: if node.dest: self.emit('DUP_TOP') - self.visit(child) + child.accept( self ) if node.dest: self.emit('ROT_TWO') self.emit('PRINT_ITEM_TO') @@ -1051,25 +1051,25 @@ def visitReturn(self, node): self.set_lineno(node) - self.visit(node.value) + node.value.accept( self ) self.emit('RETURN_VALUE') def visitYield(self, node): self.set_lineno(node) - self.visit(node.value) + node.value.accept( self ) self.emit('YIELD_VALUE') # slice and subscript stuff def visitSlice(self, node, aug_flag=None): # aug_flag is used by visitAugSlice - self.visit(node.expr) + node.expr.accept( self ) slice = 0 if node.lower: - self.visit(node.lower) + node.lower.accept( self ) slice = slice | 1 if node.upper: - self.visit(node.upper) + node.upper.accept( self ) slice = slice | 2 if aug_flag: if slice == 0: @@ -1089,9 +1089,9 @@ raise def visitSubscript(self, node, aug_flag=None): - self.visit(node.expr) + node.expr.accept( self ) for sub in node.subs: - self.visit(sub) + sub.accept( self ) if aug_flag: self.emit('DUP_TOPX', 2) if len(node.subs) > 1: @@ -1106,8 +1106,8 @@ # binary ops def binaryOp(self, node, op): - self.visit(node.left) - self.visit(node.right) + node.left.accept( self ) + node.right.accept( self ) self.emit(op) def visitAdd(self, node): @@ -1140,7 +1140,7 @@ # unary ops def unaryOp(self, node, op): - self.visit(node.expr) + node.expr.accept( self ) self.emit(op) def visitInvert(self, node): @@ -1164,9 +1164,9 @@ # bit ops def bitOp(self, nodes, op): - self.visit(nodes[0]) + nodes[0].accept( self ) for node in nodes[1:]: - self.visit(node) + node.accept( self ) self.emit(op) def visitBitand(self, node): @@ -1186,18 +1186,18 @@ def visitTuple(self, node): self.set_lineno(node) for elt in node.nodes: - self.visit(elt) + elt.accept( self ) self.emit('BUILD_TUPLE', len(node.nodes)) def visitList(self, node): self.set_lineno(node) for elt in node.nodes: - self.visit(elt) + elt.accept( self ) self.emit('BUILD_LIST', len(node.nodes)) def visitSliceobj(self, node): for child in node.nodes: - self.visit(child) + child.accept( self ) self.emit('BUILD_SLICE', len(node.nodes)) def visitDict(self, node): @@ -1205,8 +1205,8 @@ self.emit('BUILD_MAP', 0) for k, v in node.items: self.emit('DUP_TOP') - self.visit(k) - self.visit(v) + k.accept( self ) + v.accept( self ) self.emit('ROT_THREE') self.emit('STORE_SUBSCR') @@ -1259,7 +1259,7 @@ def visitDiscard(self, node): # XXX Discard means it's an expression. Perhaps this is a bad # name. - self.visit(node.expr) + node.expr.accept( self ) self.emit('PRINT_EXPR') class AbstractFunctionCode: Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Tue Aug 23 19:58:15 2005 @@ -211,7 +211,7 @@ def __init__(self, name, module): self.__super_init(name, module, name) -class SymbolVisitor: +class SymbolVisitor(ast.ASTVisitor): def __init__(self): self.scopes = {} self.klass = None @@ -220,22 +220,22 @@ def visitModule(self, node): scope = self.module = self.scopes[node] = ModuleScope() - self.visit(node.node, scope) + node.node.accept(self, scope) visitExpression = visitModule def visitFunction(self, node, parent): if node.decorators: - self.visit(node.decorators, parent) + node.decorators.accept(self, parent) parent.add_def(node.name) for n in node.defaults: - self.visit(n, parent) + n.accept( self, parent) scope = FunctionScope(node.name, self.module, self.klass) if parent.nested or isinstance(parent, FunctionScope): scope.nested = 1 self.scopes[node] = scope self._do_args(scope, node.argnames) - self.visit(node.code, scope) + node.code.accept(self, scope) self.handle_free_vars(scope, parent) def visitGenExpr(self, node, parent): @@ -245,24 +245,24 @@ scope.nested = 1 self.scopes[node] = scope - self.visit(node.code, scope) + node.code.accept(self, scope) self.handle_free_vars(scope, parent) def visitGenExprInner(self, node, scope): for genfor in node.quals: - self.visit(genfor, scope) + genfor.accept( self, scope) - self.visit(node.expr, scope) + node.expr.accept( self, scope) def visitGenExprFor(self, node, scope): - self.visit(node.assign, scope, 1) - self.visit(node.iter, scope) + node.assign.accept(self, scope, 1) + node.iter.accept(self, scope) for if_ in node.ifs: - self.visit(if_, scope) + if_.accept( self, scope) def visitGenExprIf(self, node, scope): - self.visit(node.test, scope) + node.test.accept( self, scope) def visitLambda(self, node, parent, assign=0): # Lambda is an expression, so it could appear in an expression @@ -271,13 +271,13 @@ assert not assign for n in node.defaults: - self.visit(n, parent) + n.accept( self, parent) scope = LambdaScope(self.module, self.klass) if parent.nested or isinstance(parent, FunctionScope): scope.nested = 1 self.scopes[node] = scope self._do_args(scope, node.argnames) - self.visit(node.code, scope) + node.code.accept(self, scope) self.handle_free_vars(scope, parent) def _do_args(self, scope, args): @@ -296,7 +296,7 @@ def visitClass(self, node, parent): parent.add_def(node.name) for n in node.bases: - self.visit(n, parent) + n.accept(self, parent) scope = ClassScope(node.name, self.module) if parent.nested or isinstance(parent, FunctionScope): scope.nested = 1 @@ -306,7 +306,7 @@ self.scopes[node] = scope prev = self.klass self.klass = node.name - self.visit(node.code, scope) + node.code.accept(self, scope) self.klass = prev self.handle_free_vars(scope, parent) @@ -325,11 +325,11 @@ # operations that bind new names def visitFor(self, node, scope): - self.visit(node.assign, scope, 1) - self.visit(node.list, scope) - self.visit(node.body, scope) + node.assign.accept( self, scope, 1) + node.list.accept( self, scope) + node.body.accept( self, scope) if node.else_: - self.visit(node.else_, scope) + node.else_.accept( self, scope) def visitFrom(self, node, scope): for name, asname in node.names: @@ -362,34 +362,34 @@ the assign flag to their children. """ for n in node.nodes: - self.visit(n, scope, 1) - self.visit(node.expr, scope) + n.accept( self, scope, 1) + node.expr.accept( self, scope) def visitAssName(self, node, scope, assign=1): scope.add_def(node.name) def visitAssAttr(self, node, scope, assign=0): - self.visit(node.expr, scope, 0) + node.expr.accept( self, scope, 0) def visitSubscript(self, node, scope, assign=0): - self.visit(node.expr, scope, 0) + node.expr.accept( self, scope, 0) for n in node.subs: - self.visit(n, scope, 0) + n.accept( self, scope, 0) def visitSlice(self, node, scope, assign=0): - self.visit(node.expr, scope, 0) + node.expr.accept( self, scope, 0) if node.lower: - self.visit(node.lower, scope, 0) + node.lower.accept( self, scope, 0) if node.upper: - self.visit(node.upper, scope, 0) + node.upper.accept( self, scope, 0) def visitAugAssign(self, node, scope): # If the LHS is a name, then this counts as assignment. # Otherwise, it's just use. - self.visit(node.node, scope) + node.node.accept( self, scope) if isinstance(node.node, ast.Name): - self.visit(node.node, scope, 1) # XXX worry about this - self.visit(node.expr, scope) + node.node.accept( self, scope, 1) # XXX worry about this + node.expr.accept( self, scope) # prune if statements if tests are false @@ -401,16 +401,16 @@ if type(test.value) in self._const_types: if not test.value: continue - self.visit(test, scope) - self.visit(body, scope) + test.accept( self, scope) + body.accept( self, scope) if node.else_: - self.visit(node.else_, scope) + node.else_.accept( self, scope) # a yield statement signals a generator def visitYield(self, node, scope): scope.generator = 1 - self.visit(node.value, scope) + node.value.accept( self, scope) def sort(l): l = l[:] Modified: pypy/dist/pypy/interpreter/astcompiler/visitor.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/visitor.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/visitor.py Tue Aug 23 19:58:15 2005 @@ -106,6 +106,10 @@ walker.preorder(tree, visitor) return walker.visitor +def walk(tree, visitor, verbose=None): + tree.accept( visitor ) + return visitor + def dumpNode(node): print node.__class__ for attr in dir(node): Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Tue Aug 23 19:58:15 2005 @@ -281,7 +281,7 @@ first_child = stmt.nodes[0] if isinstance(first_child, ast.Discard): expr = first_child.expr - if isinstance(expr, StringConst): + if isinstance(expr, ast.StringConst): # This *is* a docstring, remove it from stmt list del stmt.nodes[0] doc = expr.string_value @@ -495,14 +495,14 @@ elif top.name == tok.NAME: builder.push( ast.Name(top.get_value()) ) elif top.name == tok.NUMBER: - builder.push(NumberConst(eval_number(top.get_value()))) + builder.push(ast.NumberConst(eval_number(top.get_value()))) elif top.name == tok.STRING: # need to concatenate strings in atoms s = '' for token in atoms: assert isinstance(token, TokenObject) s += eval_string(token.get_value()) - builder.push(StringConst(s)) + builder.push(ast.StringConst(s)) elif top.name == tok.BACKQUOTE: builder.push(ast.Backquote(atoms[1])) else: @@ -707,7 +707,7 @@ for n in range(0,l,2): node = atoms[n] if isinstance(node, TokenObject) and node.name == tok.NEWLINE: - nodes.append(ast.Discard(NoneConst())) + nodes.append(ast.Discard(ast.NoneConst())) else: nodes.append(node) builder.push(ast.Stmt(nodes)) @@ -717,7 +717,7 @@ if len(atoms) > 2: assert False, "return several stmts not implemented" elif len(atoms) == 1: - builder.push(ast.Return(NoneConst(), None)) # XXX lineno + builder.push(ast.Return(ast.NoneConst(), None)) # XXX lineno else: builder.push(ast.Return(atoms[1], None)) # XXX lineno @@ -851,7 +851,7 @@ sliceobj_infos = [] for value in sliceinfos: if value is None: - sliceobj_infos.append(NoneConst()) + sliceobj_infos.append(ast.NoneConst()) else: sliceobj_infos.append(value) builder.push(SlicelistObject('sliceobj', sliceobj_infos, None)) @@ -1306,40 +1306,6 @@ } ## Stack elements definitions ################################### -class StringConst(ast.Const): - """specicifc Const node for strings""" - def __init__(self, value, lineno=None): - self.lineno = lineno - # don't use "value" for attribute's name to avoid confusing - # the annotator - self.string_value = value - - def __repr__(self): - return "Const(%s)" % (repr(self.string_value),) - - def getChildren(self): - return self.string_value, - -class NumberConst(ast.Const): - """specific Const node for numbers""" - def __init__(self, value, lineno=None): - self.lineno = lineno - # don't use "value" for attribute's name to avoid confusing - # the annotator - self.number_value = value - - def __repr__(self): - return "Const(%s)" % (repr(self.number_value),) - - def getChildren(self): - return self.number_value, - -class NoneConst(ast.Const): - """specific Const node for None (probably not really needed)""" - def __init__(self, lineno=None): - self.lineno = lineno - self.value = None - class BaseRuleObject(ast.Node): """Base class for unnamed rules""" Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Tue Aug 23 19:58:15 2005 @@ -7,6 +7,7 @@ from pypy.interpreter.astcompiler import ast, misc, pycodegen +from test_astbuilder import TESTS TARGET_DICT = { 'single' : 'single_input', @@ -31,17 +32,18 @@ def compare_code( code1, code2 ): - print "Filename", code1.co_filename, code2.co_filename + #print "Filename", code1.co_filename, code2.co_filename assert code1.co_filename == code2.co_filename - print repr(code1.co_code) - print repr(code2.co_code) + #print repr(code1.co_code) + #print repr(code2.co_code) assert code1.co_code == code2.co_code + assert code1.co_varnames == code2.co_varnames def check_compile( expr ): import new ast_tree = ast_parse_expr( expr ) misc.set_filename("", ast_tree) - print ast_tree + #print ast_tree codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) code1 = new.code(*codegenerator.getCode()) code2 = ast_compile( expr ) @@ -65,3 +67,10 @@ print x,y,z,t,u """ check_compile( code ) + + + +def test_basic_astgen(): + for family in TESTS: + for expr in family: + yield check_compile, expr From tismer at codespeak.net Tue Aug 23 20:06:01 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 20:06:01 +0200 (CEST) Subject: [pypy-svn] r16335 - pypy/dist/pypy/lib/_stablecompiler Message-ID: <20050823180601.04EA627B3D@code1.codespeak.net> Author: tismer Date: Tue Aug 23 20:06:01 2005 New Revision: 16335 Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py Log: not explicitly closing files is not RPython ATM. Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Tue Aug 23 20:06:01 2005 @@ -30,9 +30,13 @@ import os, marshal done = False data = marshal.dumps( (tuples, filename, mode, done) ) - file(DUMPFILE, "wb").write(data) + f = file(DUMPFILE, "wb") + f.write(data) + f.close() os.system('%s fakecompiler.py' % get_python()) - data = file(DUMPFILE, "rb").read() + f = file(DUMPFILE, "rb") + data = f.read() + f.close() code, filename, mode, done = marshal.loads(data) if not done: raise ValueError, "could not fake compile!" @@ -40,6 +44,8 @@ def get_python(): try: - return file('pythonname').read().strip() + f = file('pythonname') + res = f.read().strip() + f.close() except IOError: raise ValueError, "I need a local file 'pythonname'" From hpk at codespeak.net Tue Aug 23 20:18:19 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 23 Aug 2005 20:18:19 +0200 (CEST) Subject: [pypy-svn] r16338 - pypy/dist/lib-python Message-ID: <20050823181819.45CCC27B3F@code1.codespeak.net> Author: hpk Date: Tue Aug 23 20:18:19 2005 New Revision: 16338 Modified: pypy/dist/lib-python/conftest.py Log: tempfile is not core, is it? Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Tue Aug 23 20:18:19 2005 @@ -679,7 +679,8 @@ RegrTest('test_textwrap.py', enabled=True), RegrTest('test_thread.py', enabled=True, usemodules="thread", core=True), RegrTest('test_threaded_import.py', usemodules="thread", enabled=True, core=True), - RegrTest('test_threadedtempfile.py', usemodules="thread", enabled=True, core=True), + RegrTest('test_threadedtempfile.py', + usemodules="thread", enabled=True, core=False), # tempfile is non-core by itself #rev 10840: ImportError: thread RegrTest('test_threading.py', usemodules="thread", enabled=True, dumbtest=1, core=True), From pedronis at codespeak.net Tue Aug 23 20:22:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 23 Aug 2005 20:22:59 +0200 (CEST) Subject: [pypy-svn] r16339 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20050823182259.3781A27B3F@code1.codespeak.net> Author: pedronis Date: Tue Aug 23 20:22:57 2005 New Revision: 16339 Added: pypy/dist/pypy/translator/c/test/test_boehm.py (contents, props changed) Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/main.h pypy/dist/pypy/translator/c/src/module.h Log: groundwork for starting with a BoehmGcPolicy (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Aug 23 20:22:57 2005 @@ -14,7 +14,7 @@ class LowLevelDatabase: - def __init__(self, translator=None, standalone=False, gcpolicy=gc.RefcountingGcPolicy): + def __init__(self, translator=None, standalone=False, gcpolicy=None): self.translator = translator self.standalone = standalone self.structdefnodes = {} @@ -24,6 +24,8 @@ self.namespace = CNameManager() if not standalone: self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator) + if gcpolicy is None: + gcpolicy = gc.RefcountingGcPolicy self.gcpolicy = gcpolicy(self) def gettypedefnode(self, T, varlength=1): Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Aug 23 20:22:57 2005 @@ -35,6 +35,12 @@ return self.pop_alive_nopyobj(expr, T) return '' + def pre_gc_code(self): + return [] + + def gc_startup_code(self): + return [] + class RefcountingInfo: deallocator = None static_deallocator = None @@ -215,3 +221,5 @@ yield 'OP_ZERO_MALLOC(%s, %s, %s);' % (esize, eresult, err) + + Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Aug 23 20:22:57 2005 @@ -16,14 +16,15 @@ _compiled = False symboltable = None - def __init__(self, translator): + def __init__(self, translator, gcpolicy=None): self.translator = translator + self.gcpolicy = gcpolicy def generate_source(self): assert self.c_source_filename is None translator = self.translator pf = self.getentrypointptr() - db = LowLevelDatabase(translator, standalone=self.standalone) + db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicy=self.gcpolicy) pfname = db.get(pf) db.complete() @@ -163,6 +164,9 @@ # generate the start-up code and put it into a function print >> f, 'char *RPython_StartupCode(void) {' print >> f, '\tchar *error = NULL;' + for line in database.gcpolicy.gc_startup_code(): + print >> f,"\t" + line + firsttime = True for node in database.containerlist: lines = list(node.startupcode()) @@ -223,6 +227,10 @@ for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) print >> f, '#include "src/g_prerequisite.h"' + + for line in database.gcpolicy.pre_gc_code(): + print >> f, line + includes = {} for node in database.globalcontainers(): for include in node.includes: Modified: pypy/dist/pypy/translator/c/src/main.h ============================================================================== --- pypy/dist/pypy/translator/c/src/main.h (original) +++ pypy/dist/pypy/translator/c/src/main.h Tue Aug 23 20:22:57 2005 @@ -8,15 +8,18 @@ { char *errmsg = "out of memory"; int i; - RPyListOfString *list = RPyListOfString_New(argc); + RPyListOfString *list; + errmsg = RPython_StartupCode(); + if (errmsg) goto error; + + list = RPyListOfString_New(argc); if (RPyExceptionOccurred()) goto error; for (i=0; i Author: hpk Date: Tue Aug 23 20:30:38 2005 New Revision: 16340 Modified: pypy/dist/pypy/objspace/std/dictobject.py Log: (hpk,arigo) fix compliancy test_userdict.py in a slightly weird way (but it appears to work) Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Tue Aug 23 20:30:38 2005 @@ -224,13 +224,17 @@ return space.w_False w_rightdiff, w_rightval = characterize(space, w_right.data, w_left) w_res = space.w_False - if w_rightdiff is not None: - w_res = space.lt(w_leftdiff, w_rightdiff) - if space.is_w(w_res, space.w_False) and space.eq_w(w_leftdiff, w_rightdiff) and w_rightval is not None: + if w_rightdiff is None: + # w_leftdiff is not None, w_rightdiff is None + return space.w_True + w_isequal = space.eq(w_leftdiff, w_rightdiff) + w_res = space.lt(w_leftdiff, w_rightdiff) + if (space.is_w(w_res, space.w_False) and + space.is_true(w_isequal) and + w_rightval is not None): w_res = space.lt(w_leftval, w_rightval) return w_res - def hash__Dict(space,w_dict): raise OperationError(space.w_TypeError,space.wrap("dict objects are unhashable")) From tismer at codespeak.net Tue Aug 23 21:59:53 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 23 Aug 2005 21:59:53 +0200 (CEST) Subject: [pypy-svn] r16342 - pypy/dist/pypy/module/posix Message-ID: <20050823195953.45F4427B3F@code1.codespeak.net> Author: tismer Date: Tue Aug 23 21:59:52 2005 New Revision: 16342 Modified: pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/module/posix/interp_posix.py Log: had to add os.system to our posix file as well Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Tue Aug 23 21:59:52 2005 @@ -24,6 +24,7 @@ 'fstat' : 'interp_posix.fstat', 'stat' : 'interp_posix.stat', 'dup' : 'interp_posix.dup', + 'system' : 'interp_posix.system', } if hasattr(os, 'ftruncate'): interpleveldefs['ftruncate'] = 'interp_posix.ftruncate' Modified: pypy/dist/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/dist/pypy/module/posix/interp_posix.py (original) +++ pypy/dist/pypy/module/posix/interp_posix.py Tue Aug 23 21:59:52 2005 @@ -116,3 +116,12 @@ else: return space.wrap(newfd) dup.unwrap_spec = [ObjSpace, int] + +def system(space, cmd): + try: + rc = os.system(cmd) + except OSError, e: + raise wrap_oserror(space, e) + else: + return space.wrap(rc) +system.unwrap_spec = [ObjSpace, str] From ludal at codespeak.net Wed Aug 24 10:37:03 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Wed, 24 Aug 2005 10:37:03 +0200 (CEST) Subject: [pypy-svn] r16346 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050824083703.C20DB27B3F@code1.codespeak.net> Author: ludal Date: Wed Aug 24 10:37:01 2005 New Revision: 16346 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Log: some tests can't pass with 2.3 some don't include them if we run 2.3 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 24 10:37:01 2005 @@ -223,6 +223,9 @@ 'import a.b.c.d as abcd', 'from os import path', 'from os import path, system', + ] + +imports_newstyle = [ 'from os import path, system,', 'from os import path as P, system as S,', 'from os import (path as P, system as S,)', @@ -405,6 +408,7 @@ attraccess, slices, imports, + imports_newstyle, asserts, execs, prints, @@ -445,7 +449,6 @@ print print "BUILT:", r1.rule_stack[-1] print "-" * 30 - # r1.rule_stack[-1].equals(ast) assert nodes_equal( ast, r1.rule_stack[-1]), 'failed on %r' % (expr) @@ -502,7 +505,7 @@ source = file(filepath).read() yield check_expression, source, 'exec' -# FIXME: find the sys' attriubte that define this +# FIXME: find the sys' attribute that define this STDLIB_PATH = os.path.dirname(os.__file__) def test_on_stdlib(): py.test.skip('too ambitious for now (and time consuming)') Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Wed Aug 24 10:37:01 2005 @@ -7,8 +7,35 @@ from pypy.interpreter.astcompiler import ast, misc, pycodegen -from test_astbuilder import TESTS - +from test_astbuilder import expressions, comparisons, funccalls, backtrackings,\ + listmakers, genexps, dictmakers, multiexpr, attraccess, slices, imports,\ + asserts, execs, prints, globs, raises, imports_newstyle + + +TESTS = [ + expressions, + comparisons, + funccalls, + backtrackings, + listmakers, + dictmakers, + multiexpr, + attraccess, + slices, + imports, + execs, + prints, + globs, + raises, + ] + +import sys +if sys.version_info[0]==2 and sys.version_info[1]>=4: + # genexps and new style import don't work on python2.3 + TESTS.append(genexps) + TESTS.append(imports_newstyle) + # assertions give different bytecode with 2.4 (optimize if __debug__) + TESTS.append(asserts) TARGET_DICT = { 'single' : 'single_input', 'exec' : 'file_input', @@ -36,13 +63,20 @@ assert code1.co_filename == code2.co_filename #print repr(code1.co_code) #print repr(code2.co_code) - assert code1.co_code == code2.co_code + if code1.co_code != code2.co_code: + import dis + print "Code from pypy:" + dis.dis(code1) + print "Code from python", sys.version + dis.dis(code2) + assert code1.co_code == code2.co_code assert code1.co_varnames == code2.co_varnames def check_compile( expr ): import new ast_tree = ast_parse_expr( expr ) misc.set_filename("", ast_tree) + print "Compiling:", expr #print ast_tree codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) code1 = new.code(*codegenerator.getCode()) From arigo at codespeak.net Wed Aug 24 10:44:16 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 10:44:16 +0200 (CEST) Subject: [pypy-svn] r16347 - pypy/extradoc/sprintinfo Message-ID: <20050824084416.129AF27B41@code1.codespeak.net> Author: arigo Date: Wed Aug 24 10:44:15 2005 New Revision: 16347 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: Wednesday morning status. Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Wed Aug 24 10:44:15 2005 @@ -30,54 +30,38 @@ sunday 28th sprinting / technical summary/some future planning monday 29th sprinting/eu-meeting/cleanup -Release (PyPy-0.7) (hpk, .):: +Release (PyPy-0.7):: - Documentation work: - - update architecture "status of the implementation (May 2005)" - to reflect the 0.7 situation - update getting_started.txt to reflect the 0.7 release and include instruction on how to translate - possibly streamline the tool chain (for genc/llvm) - do we have an easy-to-explain tool chain working for win32? - - maybe globally use "bytecode interpreter" instead of "plain interpreter" - - write 0.7.0 release announcement + README - fix download locations, prepare/try out packaging - - regenerate contributors in LICENSE file - - revisit/refine LICENSE files - - put a LICENSE file in lib-python/ - - strip out a number of names (especially the ones that - have agreed to that on pypy-dev with the 0.6 release) - RELEASE CUTTING friday morning: - copy pypy/dist to pypy/release/0.7.x and work on 0.7.x regarding remaining release issues - which documentation should be served on the web page? Probably just serving dist would fit for now. - Later in September we should look into splitting - "trunk" and release-documentation. - - do we introduce pypy/trunk finally? Translation - - Finish GIL-based threading: backend support, fix bugs? (arigo, rxe) + - Finish GIL-based threading: backend support, fix bugs? - adding backend support is in-progress + mostly done (missing: rtyper support for dict with int keys) - - (Decide whether to try to implement other threading locking policies) - (probably not at the moment, let's see) - - - Isolate refcounting in genc, and (cfbolz, pedronis) + - Isolate refcounting in genc, and have an option to enable and use Boehm instead - in progress of adding GCPolicy that encapsulates refcounting - and is to be called from all places that now hardcode refcounting. + isolating done, there is a test for Boehm, but not implemented -2.4.1 Compliance (arre, tismer):: +2.4.1 Compliance:: - Recategorize the tests in core/non-core ( = language compliancy) 41 current-core tests should not be in core, 11 current-non-core tests should be in core 5 are about threading (should be core?) - - test_unicode, test_codecs (ale, jacob) + - test_unicode, test_codecs test_unicode has one remaining error involving eval(unicode) which means that compile(unicode) does not work currently. (see issue in the tracker, ludovic will try to look @@ -90,7 +74,7 @@ - Some other "non-core" tests revealing real bugs/problems? - from wednesday morning on most of us should work - on compliancy related issues + on compliancy related issues (mostly everybody) - (holger) try to fix the problem that you have to be in 2.4.1/test in order to successfully run tests @@ -105,8 +89,7 @@ st->ast mostly done, should go into the release (ludal, nik) integrated with a runtime option need to fix astcompiler - ast->bytecode is not going to be done for the release - (kept at app-level) + ast->bytecode may be done for the release? in-progress - compiling unicode strings (see failing test_builtins) https://codespeak.net/issue/pypy-dev/issue97 @@ -116,6 +99,7 @@ inputs that are a single string are considered docstrings (also single unicode strings are considered docstrings) + no progress on the bugs Built-in modules:: @@ -125,6 +109,7 @@ (try with the current _sre and its interp-level parts, otherwise just use the app-level one) (nik) in progress (trying to get '_sre' to translate) + ^^^ getting there - (Review builtin modules again to see if we missed something) - 'math' must be finished (math.log()) @@ -134,12 +119,12 @@ for the release - Review Hildes_to_Heidel.txt contents too -LLVM backend:: +LLVM backend (richard, eric):: - Improvement work to stabilize and match genc - (Try to share code with genc?) -GC:: +GC (carl friedrich, samuele):: - Complete SoC GC framework (cfbolz) in-progress: two more nights or so. From nik at codespeak.net Wed Aug 24 11:12:52 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 24 Aug 2005 11:12:52 +0200 (CEST) Subject: [pypy-svn] r16348 - pypy/dist/pypy/module/__builtin__ Message-ID: <20050824091252.C254027B3F@code1.codespeak.net> Author: nik Date: Wed Aug 24 11:12:51 2005 New Revision: 16348 Modified: pypy/dist/pypy/module/__builtin__/app_buffer.py Log: added dumb __repr__ method to make test_repr happy Modified: pypy/dist/pypy/module/__builtin__/app_buffer.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_buffer.py (original) +++ pypy/dist/pypy/module/__builtin__/app_buffer.py Wed Aug 24 11:12:51 2005 @@ -62,3 +62,7 @@ def __len__(self): return len(self.buf) + + def __repr__(self): + # We support only read-only buffers anyway + return "" From arigo at codespeak.net Wed Aug 24 11:17:10 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 11:17:10 +0200 (CEST) Subject: [pypy-svn] r16349 - in pypy/dist/pypy: lib module/_codecs module/recparser objspace/std rpython rpython/test translator/llvm2 Message-ID: <20050824091710.A979D27B3F@code1.codespeak.net> Author: arigo Date: Wed Aug 24 11:17:07 2005 New Revision: 16349 Modified: pypy/dist/pypy/lib/binascii.py pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/recparser/pyparser.py pypy/dist/pypy/objspace/std/iterobject.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/test/test_rstr.py pypy/dist/pypy/translator/llvm2/pyxwrapper.py Log: untabify. Modified: pypy/dist/pypy/lib/binascii.py ============================================================================== --- pypy/dist/pypy/lib/binascii.py (original) +++ pypy/dist/pypy/lib/binascii.py Wed Aug 24 11:17:07 2005 @@ -456,38 +456,38 @@ return ''.join(result) crctab_hqx = [ - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, ] def crc_hqx(s, crc): @@ -618,7 +618,7 @@ crc = crc_32_tab[(crc ^ long(ord(c))) & 0xffL] ^ (crc >> 8) #/* Note: (crc >> 8) MUST zero fill on left - result = crc ^ 0xffffffffL + result = crc ^ 0xffffffffL return result Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Wed Aug 24 11:17:07 2005 @@ -101,7 +101,7 @@ codecs.register_error that can handle ValueErrors. """ if encoding == None: - encoding = sys.getdefaultencoding() + encoding = sys.getdefaultencoding() if isinstance(encoding,str): encoder = lookup(encoding)[0] if encoder and isinstance(errors,str): @@ -123,7 +123,7 @@ able to handle ValueErrors. """ if encoding == None: - encoding = sys.getdefaultencoding() + encoding = sys.getdefaultencoding() if isinstance(encoding,str): decoder = lookup(encoding)[1] if decoder and isinstance(errors,str): @@ -374,10 +374,10 @@ """ pass ## return (PyUnicode_EncodeMBCS( -## (obj), -## len(obj), -## errors), -## len(obj)) +## (obj), +## len(obj), +## errors), +## len(obj)) def ascii_encode( obj,errors='strict'): @@ -508,10 +508,10 @@ ## indicate whether a UTF-7 character is special i.e. cannot be directly ## encoded: -## 0 - not special -## 1 - special -## 2 - whitespace (optional) -## 3 - RFC2152 Set O (optional) +## 0 - not special +## 1 - special +## 2 - whitespace (optional) +## 3 - RFC2152 Set O (optional) utf7_special = [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, @@ -656,7 +656,7 @@ elif SPECIAL(ch,0,0) : raise UnicodeDecodeError,"unexpected special character" - + else: p += ch else: @@ -799,11 +799,11 @@ pos += 1 continue #endif - #/* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */ + #/* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */ elif (ord(ch) >= 0xD800 and ord(ch) < 0xDC00): pos += 1 ch2 = s[pos] - + if (ord(ch2) >= 0xDC00 and ord(ch2) <= 0xDFFF): ucs = (((ord(ch) & 0x03FF) << 10) | (ord(ch2) & 0x03FF)) + 0x00010000 p += '\\' @@ -811,10 +811,10 @@ p += '%08x'%ucs pos += 1 continue - - #/* Fall through: isolated surrogates are copied as-is */ - pos -= 1 - + + #/* Fall through: isolated surrogates are copied as-is */ + pos -= 1 + #/* Map 16-bit characters to '\uxxxx' */ if (ord(ch) >= 256): p += '\\' @@ -879,8 +879,8 @@ if not type(unistr) == unicode: raise TypeError return PyUnicode_EncodeASCII(unicode(unistr), - len(unicode), - None) + len(unicode), + None) def PyUnicode_DecodeUTF16Stateful(s,size,errors,byteorder='native',consumed=None): @@ -908,19 +908,19 @@ bom = (ord(s[ihi]) << 8) | ord(s[ilo]) #ifdef BYTEORDER_IS_LITTLE_ENDIAN if sys.byteorder == 'little': - if (bom == 0xFEFF): - q += 2 - bo = -1 - elif bom == 0xFFFE: - q += 2 - bo = 1 + if (bom == 0xFEFF): + q += 2 + bo = -1 + elif bom == 0xFFFE: + q += 2 + bo = 1 else: - if bom == 0xFEFF: - q += 2 - bo = 1 - elif bom == 0xFFFE: - q += 2 - bo = -1 + if bom == 0xFEFF: + q += 2 + bo = 1 + elif bom == 0xFFFE: + q += 2 + bo = -1 elif byteorder == 'little': bo = -1 else: @@ -941,32 +941,32 @@ while (q < len(s)): - #/* remaining bytes at the end? (size should be even) */ - if (len(s)-q<2): - if (consumed): + #/* remaining bytes at the end? (size should be even) */ + if (len(s)-q<2): + if (consumed): break - errmsg = "truncated data" - startinpos = q - endinpos = len(s) - unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) -# /* The remaining input chars are ignored if the callback -## chooses to skip the input */ - - ch = (ord(s[q+ihi]) << 8) | ord(s[q+ilo]) - q += 2 - - if (ch < 0xD800 or ch > 0xDFFF): - p += unichr(ch) - continue + errmsg = "truncated data" + startinpos = q + endinpos = len(s) + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) +# /* The remaining input chars are ignored if the callback +## chooses to skip the input */ + + ch = (ord(s[q+ihi]) << 8) | ord(s[q+ilo]) + q += 2 + + if (ch < 0xD800 or ch > 0xDFFF): + p += unichr(ch) + continue - #/* UTF-16 code pair: */ + #/* UTF-16 code pair: */ if (q >= len(s)): errmsg = "unexpected end of data" startinpos = q-2 endinpos = len(s) - unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) - if (0xD800 <= ch and ch <= 0xDBFF): + if (0xD800 <= ch and ch <= 0xDBFF): ch2 = (ord(s[q+ihi]) << 8) | ord(s[q+ilo]) q += 2 if (0xDC00 <= ch2 and ch2 <= 0xDFFF): @@ -980,16 +980,16 @@ continue else: - errmsg = "illegal UTF-16 surrogate" + errmsg = "illegal UTF-16 surrogate" startinpos = q-4 endinpos = startinpos+2 - unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) - - errmsg = "illegal encoding" - startinpos = q-2 - endinpos = startinpos+2 - unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) - + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) + + errmsg = "illegal encoding" + startinpos = q-2 + endinpos = startinpos+2 + unicode_call_errorhandler(errors,'utf-16',errmsg,s,startinpos,endinpos,True) + return p, q, bo # moved out of local scope, especially because it didn't @@ -1045,7 +1045,7 @@ pass #### /* If there are no characters, bail now! */ ## if (size==0) -## return "" +## return "" ## from ctypes import * ## WideCharToMultiByte = windll.kernel32.WideCharToMultiByte #### /* First get the size of the result */ @@ -1129,7 +1129,7 @@ endinpos = size res = unicode_call_errorhandler( errors, "utf8", errmsg, - s, startinpos, endinpos) + s, startinpos, endinpos) p += res[0] pos = res[1] if n == 0: @@ -1186,13 +1186,13 @@ ((ord(s[pos+1]) & 0x3f) << 6) +\ (ord(s[pos+2]) & 0x3f) -## /* Note: UTF-8 encodings of surrogates are considered -## legal UTF-8 sequences; +## /* Note: UTF-8 encodings of surrogates are considered +## legal UTF-8 sequences; ## -## XXX For wide builds (UCS-4) we should probably try -## to recombine the surrogates into a single code -## unit. -## */ +## XXX For wide builds (UCS-4) we should probably try +## to recombine the surrogates into a single code +## unit. +## */ if c < 0x0800: errmsg = "illegal encoding" endinpos = startinpos+3 @@ -1225,7 +1225,7 @@ if ((c < 0x10000) or (c > 0x10ffff)): #/* minimum value allowed for 4 byte encoding */ #/* maximum value allowed for UTF-16 */ - + errmsg = "illegal encoding" startinpos = pos endinpos = startinpos+4 @@ -1252,15 +1252,15 @@ ## default: ## /* Other sizes are only needed for UCS-4 */ errmsg = "unsupported Unicode code range" - startinpos = pos - endinpos = startinpos+n - res = unicode_call_errorhandler( + startinpos = pos + endinpos = startinpos+n + res = unicode_call_errorhandler( errors, "utf8", errmsg, s, startinpos, endinpos) p += res[0] pos = res[1] - #continue + #continue if (consumed): consumed = pos @@ -1520,17 +1520,17 @@ p = [] for ch in s: -# /* Map 32-bit characters to '\Uxxxxxxxx' */ +# /* Map 32-bit characters to '\Uxxxxxxxx' */ if (ord(ch) >= 0x10000): p += '\\' p += 'U' p += '%08x'%(ord(ch)) elif (ord(ch) >= 256) : -# /* Map 16-bit characters to '\uxxxx' */ +# /* Map 16-bit characters to '\uxxxx' */ p += '\\' p += 'u' p += '%04x'%(ord(ch)) -# /* Copy everything else as-is */ +# /* Copy everything else as-is */ else: p += chr(ord(ch)) @@ -1566,7 +1566,7 @@ inpos = 0 res = [] while (inpos") ## - #/* done with this character => adjust input position */ + #/* done with this character => adjust input position */ inpos+=1 return res @@ -1602,8 +1602,8 @@ p = [] inpos = 0 while (inpos< len(s)): - - #/* Get mapping (char ordinal -> integer, Unicode char or None) */ + + #/* Get mapping (char ordinal -> integer, Unicode char or None) */ ch = s[inpos] try: x = mapping[ord(ch)] @@ -1645,8 +1645,8 @@ continue startinpos = pos #pos += 1 -## /* \u-escapes are only interpreted iff the number of leading -## backslashes is odd */ +## /* \u-escapes are only interpreted iff the number of leading +## backslashes is odd */ bs = pos while pos < size: if (s[pos] != '\\'): @@ -1668,7 +1668,7 @@ count = 8 pos += 1 - #/* \uXXXX with 4 hex digits, \Uxxxxxxxx with 8 */ + #/* \uXXXX with 4 hex digits, \Uxxxxxxxx with 8 */ i = 0 x = 0 Modified: pypy/dist/pypy/module/recparser/pyparser.py ============================================================================== --- pypy/dist/pypy/module/recparser/pyparser.py (original) +++ pypy/dist/pypy/module/recparser/pyparser.py Wed Aug 24 11:17:07 2005 @@ -29,8 +29,8 @@ for n in node.nodes: n.visit(self) n = len(node.nodes) - start = len(self.tuple_stack_w) - n - assert start >= 0 # annotator hint + start = len(self.tuple_stack_w) - n + assert start >= 0 # annotator hint l = [ space.wrap( node.name ) ] + self.tuple_stack_w[start:] del self.tuple_stack_w[start:] self.tuple_stack_w.append( space.newtuple( l ) ) Modified: pypy/dist/pypy/objspace/std/iterobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/iterobject.py (original) +++ pypy/dist/pypy/objspace/std/iterobject.py Wed Aug 24 11:17:07 2005 @@ -80,7 +80,7 @@ w_len = space.wrap(0) w_seqiter.w_seq = None else: - w_len =space.wrap(index) + w_len =space.wrap(index) if space.is_true(space.lt(w_len,space.wrap(0))): w_len = space.wrap(0) return w_len Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Wed Aug 24 11:17:07 2005 @@ -105,8 +105,8 @@ def rtype_builtin_int(hop): if isinstance(hop.args_s[0], annmodel.SomeString): - assert 1 <= hop.nb_args <= 2 - return hop.args_r[0].rtype_int(hop) + assert 1 <= hop.nb_args <= 2 + return hop.args_r[0].rtype_int(hop) assert hop.nb_args == 1 return hop.args_r[0].rtype_int(hop) Modified: pypy/dist/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rstr.py (original) +++ pypy/dist/pypy/rpython/test/test_rstr.py Wed Aug 24 11:17:07 2005 @@ -447,14 +447,14 @@ res = int(s, base) return res for j in (10, 16, 2, 1, 36, 42, -3): - for i in range(len(s1)): - try: - expected = fn(i, j) - except ValueError: - interpret_raises(ValueError, fn, [i, j]) - else: - res = interpret(fn, [i, j]) - assert res == expected + for i in range(len(s1)): + try: + expected = fn(i, j) + except ValueError: + interpret_raises(ValueError, fn, [i, j]) + else: + res = interpret(fn, [i, j]) + assert res == expected def test_char_mul_n(): Modified: pypy/dist/pypy/translator/llvm2/pyxwrapper.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/pyxwrapper.py (original) +++ pypy/dist/pypy/translator/llvm2/pyxwrapper.py Wed Aug 24 11:17:07 2005 @@ -44,10 +44,10 @@ append(" pass") append("") if use_boehm_gc: - append("cdef extern int GC_get_heap_size()") - append("") - append("def GC_get_heap_size_wrapper():") - append(" return GC_get_heap_size()") + append("cdef extern int GC_get_heap_size()") + append("") + append("def GC_get_heap_size_wrapper():") + append(" return GC_get_heap_size()") append("") append("def %s_wrapper(%s):" % (funcgen.ref.strip("%"), ", ".join(inputargs))) append(" result = __entrypoint__%s(%s)" % (funcgen.ref.strip("%"), ", ".join(inputargs))) From ac at codespeak.net Wed Aug 24 11:27:05 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 11:27:05 +0200 (CEST) Subject: [pypy-svn] r16351 - pypy/dist/lib-python Message-ID: <20050824092705.A603327B3F@code1.codespeak.net> Author: ac Date: Wed Aug 24 11:27:05 2005 New Revision: 16351 Modified: pypy/dist/lib-python/conftest.py Log: test_profile is not core (test_profilehooks is) Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 11:27:05 2005 @@ -446,7 +446,7 @@ RegrTest('test_dis.py', enabled=True), RegrTest('test_distutils.py', enabled=True, core=True), RegrTest('test_dl.py', enabled=False, dumbtest=1), - RegrTest('test_doctest.py', enabled=True, core=True), + RegrTest('test_doctest.py', usemodules="thread", enabled=True, core=True), RegrTest('test_doctest2.py', enabled=True, core=True), RegrTest('test_dumbdbm.py', enabled=True), RegrTest('test_dummy_thread.py', enabled=True, core=True), @@ -590,7 +590,7 @@ RegrTest('test_posixpath.py', enabled=True), RegrTest('test_pow.py', enabled=True, core=True), RegrTest('test_pprint.py', enabled=True), - RegrTest('test_profile.py', enabled=True, core="maybe"), + RegrTest('test_profile.py', enabled=True), RegrTest('test_profilehooks.py', enabled=True, core=True), RegrTest('test_pty.py', enabled=False), RegrTest('test_pwd.py', enabled=False), From jacob at codespeak.net Wed Aug 24 11:28:23 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Wed, 24 Aug 2005 11:28:23 +0200 (CEST) Subject: [pypy-svn] r16353 - pypy/dist/lib-python/modified-2.4.1/email Message-ID: <20050824092823.B618427B3F@code1.codespeak.net> Author: jacob Date: Wed Aug 24 11:28:22 2005 New Revision: 16353 Removed: pypy/dist/lib-python/modified-2.4.1/email/ Log: This fixed the problem in the wrong way. The underlying problem is that CPython automatically converts a unicode return value of __str__ and __repr__ to ascii, if it only contains characters with ordinals under 127. We don't. This probably needs to be fixed in descroperation.py. From ludal at codespeak.net Wed Aug 24 11:44:29 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Wed, 24 Aug 2005 11:44:29 +0200 (CEST) Subject: [pypy-svn] r16354 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20050824094429.2F85F27B3F@code1.codespeak.net> Author: ludal Date: Wed Aug 24 11:44:27 2005 New Revision: 16354 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/astgen.py pypy/dist/pypy/interpreter/astcompiler/symbols.py Log: - remove *args on symbol visitors - put filename attribute in the root class of the ast hierarchy Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Wed Aug 24 11:44:27 2005 @@ -24,6 +24,7 @@ """Abstract base class for ast nodes.""" def __init__(self, lineno = None): self.lineno = lineno + self.filename = "" def getChildren(self): pass # implemented by subclasses Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Wed Aug 24 11:44:27 2005 @@ -287,6 +287,7 @@ """Abstract base class for ast nodes.""" def __init__(self, lineno = None): self.lineno = lineno + self.filename = "" def getChildren(self): pass # implemented by subclasses Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Wed Aug 24 11:44:27 2005 @@ -215,69 +215,102 @@ def __init__(self): self.scopes = {} self.klass = None + self.scope_stack = [] + self.assign_stack = [ False ] + def cur_assignment(self): + return self.assign_stack[-1] + + def push_assignment(self, val ): + self.assign_stack.append( val ) + + def pop_assignment(self): + self.assign_stack.pop() + + def push_scope( self, scope ): + self.scope_stack.append( scope ) + + def pop_scope( self ): + self.scope_stack.pop() + + def cur_scope( self ): + return self.scope_stack[-1] + # node that define new scopes def visitModule(self, node): scope = self.module = self.scopes[node] = ModuleScope() - node.node.accept(self, scope) + self.push_scope(scope) + node.node.accept(self) + self.pop_scope() visitExpression = visitModule - def visitFunction(self, node, parent): + def visitFunction(self, node): + parent = self.cur_scope() if node.decorators: - node.decorators.accept(self, parent) + node.decorators.accept(self) parent.add_def(node.name) for n in node.defaults: - n.accept( self, parent) + n.accept( self ) scope = FunctionScope(node.name, self.module, self.klass) if parent.nested or isinstance(parent, FunctionScope): scope.nested = 1 self.scopes[node] = scope self._do_args(scope, node.argnames) - node.code.accept(self, scope) + self.push_scope( scope ) + node.code.accept(self ) + self.pop_scope() self.handle_free_vars(scope, parent) - def visitGenExpr(self, node, parent): + def visitGenExpr(self, node ): + parent = self.cur_scope() scope = GenExprScope(self.module, self.klass); if parent.nested or isinstance(parent, FunctionScope) \ or isinstance(parent, GenExprScope): scope.nested = 1 self.scopes[node] = scope - node.code.accept(self, scope) + self.push_scope(scope) + node.code.accept(self) + self.pop_scope() self.handle_free_vars(scope, parent) - def visitGenExprInner(self, node, scope): + def visitGenExprInner(self, node ): + #scope = self.cur_scope() for genfor in node.quals: - genfor.accept( self, scope) + genfor.accept( self ) - node.expr.accept( self, scope) + node.expr.accept( self ) - def visitGenExprFor(self, node, scope): - node.assign.accept(self, scope, 1) - node.iter.accept(self, scope) + def visitGenExprFor(self, node ): + self.push_assignment( True ) + node.assign.accept(self) + self.pop_assignment() + node.iter.accept(self ) for if_ in node.ifs: - if_.accept( self, scope) + if_.accept( self ) - def visitGenExprIf(self, node, scope): - node.test.accept( self, scope) + def visitGenExprIf(self, node ): + node.test.accept( self ) - def visitLambda(self, node, parent, assign=0): + def visitLambda(self, node ): # Lambda is an expression, so it could appear in an expression # context where assign is passed. The transformer should catch # any code that has a lambda on the left-hand side. - assert not assign - + assert not self.cur_assignment() + parent = self.cur_scope() for n in node.defaults: - n.accept( self, parent) + n.accept( self ) scope = LambdaScope(self.module, self.klass) if parent.nested or isinstance(parent, FunctionScope): scope.nested = 1 self.scopes[node] = scope self._do_args(scope, node.argnames) - node.code.accept(self, scope) + self.push_scope(scope) + node.code.accept(self) + self.pop_scope() self.handle_free_vars(scope, parent) def _do_args(self, scope, args): @@ -293,10 +326,11 @@ parent.add_child(scope) scope.handle_children() - def visitClass(self, node, parent): + def visitClass(self, node): + parent = self.cur_scope() parent.add_def(node.name) for n in node.bases: - n.accept(self, parent) + n.accept(self) scope = ClassScope(node.name, self.module) if parent.nested or isinstance(parent, FunctionScope): scope.nested = 1 @@ -306,7 +340,9 @@ self.scopes[node] = scope prev = self.klass self.klass = node.name - node.code.accept(self, scope) + self.push_scope( scope ) + node.code.accept(self) + self.pop_scope() self.klass = prev self.handle_free_vars(scope, parent) @@ -316,39 +352,45 @@ # true if the name is being used as an assignment. only # expressions contained within statements may have the assign arg. - def visitName(self, node, scope, assign=0): - if assign: + def visitName(self, node ): + scope = self.cur_scope() + if self.cur_assignment(): scope.add_def(node.varname) else: scope.add_use(node.varname) # operations that bind new names - def visitFor(self, node, scope): - node.assign.accept( self, scope, 1) - node.list.accept( self, scope) - node.body.accept( self, scope) + def visitFor(self, node ): + self.push_assignment( True ) + node.assign.accept( self ) + self.pop_assignment() + node.list.accept( self ) + node.body.accept( self ) if node.else_: - node.else_.accept( self, scope) + node.else_.accept( self ) - def visitFrom(self, node, scope): + def visitFrom(self, node ): + scope = self.cur_scope() for name, asname in node.names: if name == "*": continue scope.add_def(asname or name) - def visitImport(self, node, scope): + def visitImport(self, node ): + scope = self.cur_scope() for name, asname in node.names: i = name.find(".") if i > -1: name = name[:i] scope.add_def(asname or name) - def visitGlobal(self, node, scope): + def visitGlobal(self, node ): + scope = self.cur_scope() for name in node.names: scope.add_global(name) - def visitAssign(self, node, scope): + def visitAssign(self, node ): """Propagate assignment flag down to child nodes. The Assign node doesn't itself contains the variables being @@ -361,56 +403,76 @@ visitor handles these nodes specially; they do not propagate the assign flag to their children. """ + self.push_assignment( True ) for n in node.nodes: - n.accept( self, scope, 1) - node.expr.accept( self, scope) + n.accept( self ) + self.pop_assignment() + node.expr.accept( self ) - def visitAssName(self, node, scope, assign=1): + def visitAssName(self, node ): + scope = self.cur_scope() scope.add_def(node.name) - def visitAssAttr(self, node, scope, assign=0): - node.expr.accept( self, scope, 0) - - def visitSubscript(self, node, scope, assign=0): - node.expr.accept( self, scope, 0) + def visitAssAttr(self, node ): + self.push_assignment( False ) + node.expr.accept( self ) + self.pop_assignment() + + def visitSubscript(self, node ): + self.push_assignment( False ) + node.expr.accept( self ) for n in node.subs: - n.accept( self, scope, 0) + n.accept( self ) + self.pop_assignment() - def visitSlice(self, node, scope, assign=0): - node.expr.accept( self, scope, 0) + def visitSlice(self, node ): + self.push_assignment( False ) + node.expr.accept( self ) if node.lower: - node.lower.accept( self, scope, 0) + node.lower.accept( self ) if node.upper: - node.upper.accept( self, scope, 0) + node.upper.accept( self ) + self.pop_assignment() - def visitAugAssign(self, node, scope): + def visitAugAssign(self, node ): # If the LHS is a name, then this counts as assignment. # Otherwise, it's just use. - node.node.accept( self, scope) + node.node.accept( self ) if isinstance(node.node, ast.Name): - node.node.accept( self, scope, 1) # XXX worry about this - node.expr.accept( self, scope) + self.push_assignment( True ) # XXX worry about this + node.node.accept( self ) + self.pop_assignment() + node.expr.accept( self ) # prune if statements if tests are false _const_types = types.StringType, types.IntType, types.FloatType - def visitIf(self, node, scope): + def visitIf(self, node ): for test, body in node.tests: if isinstance(test, ast.Const): + # XXX: Shouldn't come here anymore if type(test.value) in self._const_types: if not test.value: continue - test.accept( self, scope) - body.accept( self, scope) + if isinstance(test, ast.NumberConst): + if not test.number_value: + continue + if isinstance(test, ast.NoneConst): + continue + if isinstance(test, ast.StringConst): + if not test.string_value: + continue + test.accept( self ) + body.accept( self ) if node.else_: - node.else_.accept( self, scope) + node.else_.accept( self ) # a yield statement signals a generator - def visitYield(self, node, scope): + def visitYield(self, node ): scope.generator = 1 - node.value.accept( self, scope) + node.value.accept( self ) def sort(l): l = l[:] From hpk at codespeak.net Wed Aug 24 11:47:55 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 24 Aug 2005 11:47:55 +0200 (CEST) Subject: [pypy-svn] r16355 - in pypy/dist: lib-python pypy/tool/pytest Message-ID: <20050824094755.E2E4E27B49@code1.codespeak.net> Author: hpk Date: Wed Aug 24 11:47:55 2005 New Revision: 16355 Modified: pypy/dist/lib-python/conftest.py pypy/dist/pypy/tool/pytest/regrverbose.py Log: mirror cpython's regrtest running of tests more closely. this is slightly experimental and may break running of tests. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 11:47:55 2005 @@ -856,14 +856,14 @@ pypy_options.extend( ['--usemodules=%s' % mod for mod in regrtest.usemodules]) sopt = " ".join(pypy_options) - - if regrtest.getoutputpath(): - wrap = str(regr_script) - else: - wrap = "" + # experimental: always use regrverbose script + # previously we only did it if regrtest.outputpath() was True + # the regrverbose script now does the logic that CPython + # uses in its regrtest.py + wrap = str(regr_script) TIMEOUT = gettimeout() cmd = "%s %s %d %s %s %s %s" %(python, alarm_script, TIMEOUT, - pypy_script, wrap, sopt, fspath) + pypy_script, sopt, wrap, fspath.purebasename) return cmd def run(self): Modified: pypy/dist/pypy/tool/pytest/regrverbose.py ============================================================================== --- pypy/dist/pypy/tool/pytest/regrverbose.py (original) +++ pypy/dist/pypy/tool/pytest/regrverbose.py Wed Aug 24 11:47:55 2005 @@ -1,5 +1,13 @@ +# refer to 2.4.1/test/regrtest.py's runtest() for comparison import sys from test import test_support test_support.verbose = False sys.argv[:] = sys.argv[1:] -execfile(sys.argv[0]) + +modname = sys.argv[0] +impname = 'test.' + modname +mod = __import__(impname, globals(), locals(), [modname]) +indirect_test = getattr(mod, 'test_main', None) +if indirect_test is not None: + indirect_test() +# else the test already ran during import From arigo at codespeak.net Wed Aug 24 12:08:20 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 12:08:20 +0200 (CEST) Subject: [pypy-svn] r16356 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050824100820.1BE3E27B47@code1.codespeak.net> Author: arigo Date: Wed Aug 24 12:08:18 2005 New Revision: 16356 Modified: pypy/dist/pypy/objspace/std/test/test_unicodeobject.py pypy/dist/pypy/objspace/std/unicodeobject.py Log: Wrote unicode.__getnewargs__(). Should fix two failures in test_pickle.py. Modified: pypy/dist/pypy/objspace/std/test/test_unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_unicodeobject.py Wed Aug 24 12:08:18 2005 @@ -175,3 +175,10 @@ unichr(19), unichr(2), u'\u1234', u'\U00101234']: assert eval(repr(ustr)) == ustr + def test_getnewargs(self): + class X(unicode): + pass + x = X(u"foo\u1234") + a = x.__getnewargs__() + assert a == (u"foo\u1234",) + assert type(a[0]) is unicode Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Wed Aug 24 12:08:18 2005 @@ -97,6 +97,9 @@ raise OperationError(space.w_TypeError, space.wrap('ord() expected a character')) return space.wrap(ord(w_uni._value[0])) +def getnewargs__Unicode(space, w_uni): + return space.newtuple([W_UnicodeObject(space, w_uni._value)]) + def add__Unicode_Unicode(space, w_left, w_right): left = w_left._value right = w_right._value From ale at codespeak.net Wed Aug 24 12:21:29 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 24 Aug 2005 12:21:29 +0200 (CEST) Subject: [pypy-svn] r16357 - in pypy/dist/pypy/module/_codecs: . test Message-ID: <20050824102129.9CBA027B47@code1.codespeak.net> Author: ale Date: Wed Aug 24 12:21:28 2005 New Revision: 16357 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: Added check for trailing backslash. Detected in test_pickle. Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Wed Aug 24 12:21:28 2005 @@ -311,36 +311,39 @@ if data[i] == '\\': i += 1 - if data[i] == '\\': - res += '\\' - elif data[i] == 'n': - res += '\n' - elif data[i] == 't': - res += '\t' - elif data[i] == 'r': - res += '\r' - elif data[i] == 'b': - res += '\b' - elif data[i] == '\'': - res += '\'' - elif data[i] == '\"': - res += '\"' - elif data[i] == 'f': - res += '\f' - elif data[i] == 'a': - res += '\a' - elif data[i] == 'v': - res += '\v' - elif '0' <= data[i] <= '9': - # emulate a strange wrap-around behavior of CPython: - # \400 is the same as \000 because 0400 == 256 - octal = data[i:i+3] - res += chr(int(octal,8) & 0xFF) - i += 2 - elif data[i] == 'x': - hexa = data[i+1:i+3] - res += chr(int(hexa,16)) - i += 2 + if i >= l: + raise ValueError("Trailing \\ in string") + else: + if data[i] == '\\': + res += '\\' + elif data[i] == 'n': + res += '\n' + elif data[i] == 't': + res += '\t' + elif data[i] == 'r': + res += '\r' + elif data[i] == 'b': + res += '\b' + elif data[i] == '\'': + res += '\'' + elif data[i] == '\"': + res += '\"' + elif data[i] == 'f': + res += '\f' + elif data[i] == 'a': + res += '\a' + elif data[i] == 'v': + res += '\v' + elif '0' <= data[i] <= '9': + # emulate a strange wrap-around behavior of CPython: + # \400 is the same as \000 because 0400 == 256 + octal = data[i:i+3] + res += chr(int(octal,8) & 0xFF) + i += 2 + elif data[i] == 'x': + hexa = data[i+1:i+3] + res += chr(int(hexa,16)) + i += 2 else: res += data[i] i += 1 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Wed Aug 24 12:21:28 2005 @@ -1,6 +1,172 @@ import autopath class AppTestCodecs: + + def test_indexerror(self): + test = "\\" # trailing backslash + + raises (ValueError, test.decode,'string-escape') + + def test_insecure_pickle(self): + import pickle + insecure = ["abc", "2 + 2", # not quoted + #"'abc' + 'def'", # not a single quoted string + "'abc", # quote is not closed + "'abc\"", # open quote and close quote don't match + "'abc' ?", # junk after close quote + "'\\'", # trailing backslash + # some tests of the quoting rules + #"'abc\"\''", + #"'\\\\a\'\'\'\\\'\\\\\''", + ] + for s in insecure: + buf = "S" + s + "\012p0\012." + print s + raises (ValueError, pickle.loads, buf) + + def test_partial_utf8(self): + class Queue(object): + """ + queue: write bytes at one end, read bytes from the other end + """ + def __init__(self): + self._buffer = "" + + def write(self, chars): + self._buffer += chars + + def read(self, size=-1): + if size<0: + s = self._buffer + self._buffer = "" + return s + else: + s = self._buffer[:size] + self._buffer = self._buffer[size:] + return s + def check_partial(encoding, input, partialresults): + import codecs + + # get a StreamReader for the encoding and feed the bytestring version + # of input to the reader byte by byte. Read every available from + # the StreamReader and check that the results equal the appropriate + # entries from partialresults. + q = Queue() + r = codecs.getreader(encoding)(q) + result = u"" + for (c, partialresult) in zip(input.encode(encoding), partialresults): + q.write(c) + result += r.read() + assert result == partialresult + # check that there's nothing left in the buffers + assert r.read() == u"" + assert r.bytebuffer == "" + assert r.charbuffer == u"" + encoding = 'utf-8' + check_partial(encoding, + u"\x00\xff\u07ff\u0800\uffff", + [ + u"\x00", + u"\x00", + u"\x00\xff", + u"\x00\xff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800\uffff", + ] + ) + + def test_partial_utf16(self): + class Queue(object): + """ + queue: write bytes at one end, read bytes from the other end + """ + def __init__(self): + self._buffer = "" + + def write(self, chars): + self._buffer += chars + + def read(self, size=-1): + if size<0: + s = self._buffer + self._buffer = "" + return s + else: + s = self._buffer[:size] + self._buffer = self._buffer[size:] + return s + def check_partial(encoding, input, partialresults): + import codecs + + # get a StreamReader for the encoding and feed the bytestring version + # of input to the reader byte by byte. Read every available from + # the StreamReader and check that the results equal the appropriate + # entries from partialresults. + q = Queue() + r = codecs.getreader(encoding)(q) + result = u"" + for (c, partialresult) in zip(input.encode(encoding), partialresults): + q.write(c) + result += r.read() + assert result == partialresult + # check that there's nothing left in the buffers + assert r.read() == u"" + assert r.bytebuffer == "" + assert r.charbuffer == u"" + encoding = 'utf-16' + check_partial(encoding, + u"\x00\xff\u0100\uffff", + [ + u"", # first byte of BOM read + u"", # second byte of BOM read => byteorder known + u"", + u"\x00", + u"\x00", + u"\x00\xff", + u"\x00\xff", + u"\x00\xff\u0100", + u"\x00\xff\u0100", + u"\x00\xff\u0100\uffff", + ]) + def test_bug1098990_a(self): + import codecs, StringIO + self.encoding = 'utf-8' + s1 = u"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\r\n" + s2 = u"offending line: ladfj askldfj klasdj fskla dfzaskdj fasklfj laskd fjasklfzzzzaa%whereisthis!!!\r\n" + s3 = u"next line.\r\n" + + s = (s1+s2+s3).encode(self.encoding) + stream = StringIO.StringIO(s) + reader = codecs.getreader(self.encoding)(stream) + assert reader.readline() == s1 + assert reader.readline() == s2 + assert reader.readline() == s3 + assert reader.readline() == u"" + + def test_bug1098990_b(self): + import codecs, StringIO + self.encoding = 'utf-8' + s1 = u"aaaaaaaaaaaaaaaaaaaaaaaa\r\n" + s2 = u"bbbbbbbbbbbbbbbbbbbbbbbb\r\n" + s3 = u"stillokay:bbbbxx\r\n" + s4 = u"broken!!!!badbad\r\n" + s5 = u"againokay.\r\n" + + s = (s1+s2+s3+s4+s5).encode(self.encoding) + stream = StringIO.StringIO(s) + reader = codecs.getreader(self.encoding)(stream) + assert reader.readline() == s1 + assert reader.readline() == s2 + assert reader.readline() == s3 + assert reader.readline() == s4 + assert reader.readline() == s5 + assert reader.readline() == u"" + def test_seek_utf16le(self): # all codecs should be able to encode these import codecs, StringIO @@ -10,9 +176,7 @@ for t in xrange(5): # Test that calling seek resets the internal codec state and buffers reader.seek(0, 0) - print "before" line = reader.readline() - print "after",line assert s[:len(line)] == line From lac at codespeak.net Wed Aug 24 12:31:49 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 24 Aug 2005 12:31:49 +0200 (CEST) Subject: [pypy-svn] r16358 - pypy/dist/pypy/objspace/std Message-ID: <20050824103149.B1BAA27B47@code1.codespeak.net> Author: lac Date: Wed Aug 24 12:31:48 2005 New Revision: 16358 Modified: pypy/dist/pypy/objspace/std/typetype.py Log: Typetype is not amenable to the patching by function trick, needs to be done by hand. Modified: pypy/dist/pypy/objspace/std/typetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/typetype.py (original) +++ pypy/dist/pypy/objspace/std/typetype.py Wed Aug 24 12:31:48 2005 @@ -98,6 +98,9 @@ return space.w_None def descr__doc(space, w_type): + if space.is_w(w_type, space.w_type): + return space.wrap("""type(object) -> the object's type +type(name, bases, dict) -> a new type""") w_type = _check(space, w_type) w_result = w_type.getdictvalue(space, '__doc__') if w_result is None: From lac at codespeak.net Wed Aug 24 12:48:23 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 24 Aug 2005 12:48:23 +0200 (CEST) Subject: [pypy-svn] r16359 - in pypy/dist/pypy/tool: . test Message-ID: <20050824104823.9CC1527B47@code1.codespeak.net> Author: lac Date: Wed Aug 24 12:48:22 2005 New Revision: 16359 Modified: pypy/dist/pypy/tool/getdocstrings.py pypy/dist/pypy/tool/test/test_getdocstrings.py Log: Ok, the tool works. Modified: pypy/dist/pypy/tool/getdocstrings.py ============================================================================== --- pypy/dist/pypy/tool/getdocstrings.py (original) +++ pypy/dist/pypy/tool/getdocstrings.py Wed Aug 24 12:48:22 2005 @@ -1,6 +1,7 @@ import autopath import re from os import listdir +from sys import stdin, stdout, stderr where = autopath.pypydir + '/objspace/std/' quote = '(' + "'" + '|' + '"' + ')' @@ -9,12 +10,14 @@ # in your docstring. def mk_std_filelist(): - ''' go to pypy/objs/std and get all the *type.py files ''' + ''' go to pypy/objs/std and get all the *type.py files, except for + typetype.py which has to be patched by hand.''' filelist = [] filenames = listdir(where) for f in filenames: if f.endswith('type.py'): - filelist.append(f) + if f != 'typetype.py': + filelist.append(f) return filelist @@ -24,16 +27,16 @@ re.DOTALL ) -def compile_typedef(match): +def compile_typedef(typ): return re.compile(r"(?P\s+)" - + r"(?P" + match + + r"(?P" + typ + "_typedef = StdTypeDef+\s*\(\s*" - + quote + match + quote + ",).*" + + quote + typ + quote + ",).*" + r"(?P^\s+)" + r"(?P__new__\s*=\s*newmethod)", re.DOTALL | re.MULTILINE) -def get_pypydoc(match, sourcefile): +def get_pypydoc(sourcefile): doc = compile_doc() try: # if this works we already have a docstring @@ -44,68 +47,53 @@ return pypydoc -def sub_pypydoc(match, sourcefile, cpydoc): +def get_cpydoc(typ): + # relies on being run by CPython. try: - typedef = compile_typedef(match) - tdsearch = typedef.search(sourcefile).group('typeassign') - newsearch = typedef.search(sourcefile).group('newassign') - if not tdsearch: - print 'tdsearch, not found', match - if not newsearch: - print 'newsearch, not found', match - except AttributeError: - pass # so stringtype does not blow up. - return None - -def get_cpydoc(match): - try: - cpydoc = eval(match + '.__doc__') + cpydoc = eval(typ + '.__doc__') except NameError: # No CPython docstring cpydoc = None return cpydoc -if __name__ == '__main__': +def add_docstring(typ, sourcefile): + pypydoc = get_pypydoc(sourcefile) + cpydoc = get_cpydoc(typ) - #filenames = mk_std_filelist() - #filenames = ['basestringtype.py'] - filenames = ['tupletype.py'] + if pypydoc: + stderr.write('%s: already has a pypy docstring\n' % typ) + return None + elif not cpydoc: + stderr.write('%s: does not have a cpython docstring\n' % typ) + return None + else: + docstring="__doc__ = '''" + cpydoc + "'''," + + typedef = compile_typedef(typ) + newsearch = typedef.search(sourcefile) + if not newsearch: + stderr.write('%s: has a cpython docstring, but no __new__, to determine where to put it.\n' % typ) + return None + else: + return re.sub(newsearch.group('indent') + + newsearch.group('newassign'), + newsearch.group('indent') + + docstring + '\n' + + newsearch.group('indent') + + newsearch.group('newassign'), + sourcefile) - docstrings = [] +if __name__ == '__main__': + filenames = mk_std_filelist() + for f in filenames: - match = f[:-7] - sourcefile = file(where + f).read() + inf = file(where + f).read() + outs = add_docstring(f[:-7], inf) + if outs is not None: + outf = file(where + f, 'w') + outf.write(outs) - pypydoc = get_pypydoc(match, sourcefile) - cpydoc = get_cpydoc(match) - - if pypydoc: - print match, 'already has a pypydoc' - elif not cpydoc: - print match, 'does not have a cpydoc' - - else: - print match, 'has cpydoc. Trying to insert' - docstring="__doc__ = '''" + cpydoc + "'''" - - typedef = compile_typedef(match) - - try: - newsearch = typedef.search(sourcefile) - if newsearch: - print match, '__new__ found' - print newsearch.groupdict() - print newsearch.group('newassign') - print re.sub(newsearch.group('indent') + - newsearch.group('newassign'), - newsearch.group('indent') + - docstring + '\n' + - newsearch.group('indent') + - newsearch.group('newassign'), - sourcefile) - except AttributeError: - print match, 'no __new__ found' Modified: pypy/dist/pypy/tool/test/test_getdocstrings.py ============================================================================== --- pypy/dist/pypy/tool/test/test_getdocstrings.py (original) +++ pypy/dist/pypy/tool/test/test_getdocstrings.py Wed Aug 24 12:48:22 2005 @@ -20,7 +20,7 @@ assert mk_std_filelist() == [ 'basestringtype.py', 'unicodetype.py', 'inttype.py', 'nonetype.py', 'longtype.py', 'slicetype.py', - 'itertype.py', 'floattype.py', 'typetype.py', + 'itertype.py', 'floattype.py', 'dicttype.py', 'dictproxytype.py', 'tupletype.py', 'booltype.py', 'objecttype.py', 'stringtype.py', 'listtype.py'] From lac at codespeak.net Wed Aug 24 12:57:42 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 24 Aug 2005 12:57:42 +0200 (CEST) Subject: [pypy-svn] r16360 - pypy/dist/pypy/objspace/std Message-ID: <20050824105742.07DCA27B41@code1.codespeak.net> Author: lac Date: Wed Aug 24 12:57:39 2005 New Revision: 16360 Modified: pypy/dist/pypy/objspace/std/booltype.py pypy/dist/pypy/objspace/std/dicttype.py pypy/dist/pypy/objspace/std/floattype.py pypy/dist/pypy/objspace/std/inttype.py pypy/dist/pypy/objspace/std/listtype.py pypy/dist/pypy/objspace/std/longtype.py pypy/dist/pypy/objspace/std/objecttype.py pypy/dist/pypy/objspace/std/slicetype.py pypy/dist/pypy/objspace/std/tupletype.py Log: And these are the files that the getdocstring tool correctly inserted a docstring into Modified: pypy/dist/pypy/objspace/std/booltype.py ============================================================================== --- pypy/dist/pypy/objspace/std/booltype.py (original) +++ pypy/dist/pypy/objspace/std/booltype.py Wed Aug 24 12:57:39 2005 @@ -13,6 +13,11 @@ # ____________________________________________________________ bool_typedef = StdTypeDef("bool", int_typedef, + __doc__ = '''bool(x) -> bool + +Returns True when the argument x is true, False otherwise. +The builtins True and False are the only two instances of the class bool. +The class bool is a subclass of the class int, and cannot be subclassed.''', __new__ = newmethod(descr__new__), ) bool_typedef.acceptable_as_base_class = False Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Wed Aug 24 12:57:39 2005 @@ -106,6 +106,15 @@ # ____________________________________________________________ dict_typedef = StdTypeDef("dict", + __doc__ = '''dict() -> new empty dictionary. +dict(mapping) -> new dictionary initialized from a mapping object's + (key, value) pairs. +dict(seq) -> new dictionary initialized as if via: + d = {} + for k, v in seq: + 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]), ) Modified: pypy/dist/pypy/objspace/std/floattype.py ============================================================================== --- pypy/dist/pypy/objspace/std/floattype.py (original) +++ pypy/dist/pypy/objspace/std/floattype.py Wed Aug 24 12:57:39 2005 @@ -42,5 +42,8 @@ # ____________________________________________________________ float_typedef = StdTypeDef("float", + __doc__ = '''float(x) -> floating point number + +Convert a string or number to a floating point number, if possible.''', __new__ = newmethod(descr__new__), ) Modified: pypy/dist/pypy/objspace/std/inttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/inttype.py (original) +++ pypy/dist/pypy/objspace/std/inttype.py Wed Aug 24 12:57:39 2005 @@ -89,5 +89,13 @@ # ____________________________________________________________ int_typedef = StdTypeDef("int", + __doc__ = '''int(x[, base]) -> integer + +Convert a string or number to an integer, if possible. A floating point +argument will be truncated towards zero (this does not include a string +representation of a floating point number!) When converting a string, use +the optional base. It is an error to supply a base when converting a +non-string. If the argument is outside the integer range a long object +will be returned instead.''', __new__ = newmethod(descr__new__), ) Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Wed Aug 24 12:57:39 2005 @@ -41,6 +41,8 @@ # ____________________________________________________________ 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]), Modified: pypy/dist/pypy/objspace/std/longtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/longtype.py (original) +++ pypy/dist/pypy/objspace/std/longtype.py Wed Aug 24 12:57:39 2005 @@ -73,5 +73,12 @@ # ____________________________________________________________ long_typedef = StdTypeDef("long", + __doc__ = '''long(x[, base]) -> integer + +Convert a string or number to a long integer, if possible. A floating +point argument will be truncated towards zero (this does not include a +string representation of a floating point number!) When converting a +string, use the optional base. It is an error to supply a base when +converting a non-string.''', __new__ = newmethod(descr__new__), ) Modified: pypy/dist/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/objecttype.py (original) +++ pypy/dist/pypy/objspace/std/objecttype.py Wed Aug 24 12:57:39 2005 @@ -158,6 +158,7 @@ __str__ = gateway.interp2app(descr__str__), __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]), __hash__ = gateway.interp2app(descr__hash__), Modified: pypy/dist/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/slicetype.py (original) +++ pypy/dist/pypy/objspace/std/slicetype.py Wed Aug 24 12:57:39 2005 @@ -136,6 +136,9 @@ slice_typedef = StdTypeDef("slice", + __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__), start = slicewprop('w_start'), stop = slicewprop('w_stop'), Modified: pypy/dist/pypy/objspace/std/tupletype.py ============================================================================== --- pypy/dist/pypy/objspace/std/tupletype.py (original) +++ pypy/dist/pypy/objspace/std/tupletype.py Wed Aug 24 12:57:39 2005 @@ -17,5 +17,9 @@ # ____________________________________________________________ tuple_typedef = StdTypeDef("tuple", + __doc__ = '''tuple() -> an empty tuple +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__), ) From lac at codespeak.net Wed Aug 24 13:12:23 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 24 Aug 2005 13:12:23 +0200 (CEST) Subject: [pypy-svn] r16361 - pypy/dist/pypy/objspace/std Message-ID: <20050824111223.1048F27B41@code1.codespeak.net> Author: lac Date: Wed Aug 24 13:12:21 2005 New Revision: 16361 Modified: pypy/dist/pypy/objspace/std/basestringtype.py pypy/dist/pypy/objspace/std/itertype.py Log: These poor functions were too unpopulated for the tool to know where to insert the docstring and get the indentation correct. Modified: pypy/dist/pypy/objspace/std/basestringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/basestringtype.py (original) +++ pypy/dist/pypy/objspace/std/basestringtype.py Wed Aug 24 13:12:21 2005 @@ -4,4 +4,6 @@ # ____________________________________________________________ basestring_typedef = StdTypeDef("basestring", + __doc__ = '''Type basestring cannot be instantiated; it is the base for str and unicode.''' ) + Modified: pypy/dist/pypy/objspace/std/itertype.py ============================================================================== --- pypy/dist/pypy/objspace/std/itertype.py (original) +++ pypy/dist/pypy/objspace/std/itertype.py Wed Aug 24 13:12:21 2005 @@ -2,6 +2,12 @@ # ____________________________________________________________ iter_typedef = StdTypeDef("sequenceiterator", + __doc__ = '''iter(collection) -> iterator +iter(callable, sentinel) -> iterator + +Get an iterator from an object. In the first form, the argument must +supply its own iterator, or be a sequence. +In the second form, the callable is called until it returns the sentinel.''' ) reverse_iter_typedef = StdTypeDef("reversesequenceiterator", From lac at codespeak.net Wed Aug 24 13:23:30 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Wed, 24 Aug 2005 13:23:30 +0200 (CEST) Subject: [pypy-svn] r16362 - pypy/dist/pypy/objspace/std Message-ID: <20050824112330.A7E2327B47@code1.codespeak.net> Author: lac Date: Wed Aug 24 13:23:29 2005 New Revision: 16362 Modified: pypy/dist/pypy/objspace/std/stringtype.py Log: And because this file is called 'stringtype' not 'strtype' the tool didn't find a string.__doc__ Modified: pypy/dist/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringtype.py (original) +++ pypy/dist/pypy/objspace/std/stringtype.py Wed Aug 24 13:23:29 2005 @@ -55,5 +55,9 @@ str_typedef = StdTypeDef("str", basestring_typedef, __new__ = newmethod(descr__new__), + __doc__ = '''str(object) -> string + +Return a nice string representation of the object. +If the argument is a string, the return value is the same object.''' ) str_typedef.registermethods(globals()) From arigo at codespeak.net Wed Aug 24 13:33:06 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 13:33:06 +0200 (CEST) Subject: [pypy-svn] r16363 - in pypy/dist/pypy: interpreter lib module/thread module/thread/test objspace/std Message-ID: <20050824113306.017B127B41@code1.codespeak.net> Author: arigo Date: Wed Aug 24 13:33:02 2005 New Revision: 16363 Added: pypy/dist/pypy/module/thread/test/test_import_lock.py (contents, props changed) Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/module.py pypy/dist/pypy/lib/imp.py pypy/dist/pypy/module/thread/__init__.py pypy/dist/pypy/objspace/std/objspace.py Log: Implemented the import lock when --usemodules=thread. The import lock itself is completely done at app-level in imp.py, to provide the required interface imp.*lock*() to user programs. It's done as an __import__ hook. There is a minor hack to force imp.py to get imported when the space is done being initialized. --This line, and those below, will be ignored-- M pypy/interpreter/baseobjspace.py M pypy/interpreter/module.py AM pypy/module/thread/test/test_import_lock.py M pypy/module/thread/__init__.py M pypy/objspace/std/objspace.py M pypy/lib/imp.py Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Aug 24 13:33:02 2005 @@ -219,6 +219,12 @@ #print "setitem: space instance %-20s into builtins" % name self.setitem(self.builtin.w_dict, self.wrap(name), value) + def setup_builtin_modules(self): + "NOT_RPYTHON: only for initializing the space." + for modname, mixedname in self.get_builtinmodule_list(): + mod = self.getbuiltinmodule(modname) + mod.setup_after_space_initialization() + def initialize(self): """NOT_RPYTHON: Abstract method that should put some minimal content into the w_builtins.""" Modified: pypy/dist/pypy/interpreter/module.py ============================================================================== --- pypy/dist/pypy/interpreter/module.py (original) +++ pypy/dist/pypy/interpreter/module.py Wed Aug 24 13:33:02 2005 @@ -17,6 +17,10 @@ if w_name is not None: space.setitem(w_dict, space.wrap('__name__'), w_name) + def setup_after_space_initialization(self): + """NOT_RPYTHON: to allow built-in modules to do some more setup + after the space is fully initialized.""" + def getdict(self): return self.w_dict Modified: pypy/dist/pypy/lib/imp.py ============================================================================== --- pypy/dist/pypy/lib/imp.py (original) +++ pypy/dist/pypy/lib/imp.py Wed Aug 24 13:33:02 2005 @@ -7,8 +7,6 @@ # XXX to be reviewed -import sys, os - PY_SOURCE = 1 PY_COMPILED = 2 C_EXTENSION = 3 @@ -24,10 +22,9 @@ def get_suffixes(): return [('.py', 'U', PY_SOURCE)] -new_module = type(sys) - def find_module(name, path=None): + import sys, os if path is None: if name in sys.builtin_module_names: return (None, name, ('', '', C_BUILTIN)) @@ -43,6 +40,8 @@ def load_module(name, file, filename, description): + import sys, os + new_module = type(sys) suffix, mode, type = description module = sys.modules.get(name) @@ -75,10 +74,61 @@ raise ValueError, 'invalid description argument: %r' % (description,) -# XXX needs to be implemented when we have threads -def lock_held(): - return False -def acquire_lock(): - pass -def release_lock(): - pass +try: + # PyPy-specific interface: hint from the thread module to ask us to + # provide an import lock + from thread import _please_provide_import_lock +except ImportError: + def lock_held(): + return False + def acquire_lock(): + pass + def release_lock(): + pass +else: + del _please_provide_import_lock + import thread + + class _ImportLock: + def __init__(self): + self.lock = thread.allocate_lock() + self.in_thread = None + self.recursions = 0 + + def held(self): + return self.in_thread is not None + + def acquire(self): + myident = thread.get_ident() + if self.in_thread == myident: + self.recursions += 1 + else: + self.lock.acquire() + self.in_thread = myident + self.recursions = 1 + + def release(self): + myident = thread.get_ident() + if self.in_thread != myident: + raise RuntimeError("not holding the import lock") + self.recursions -= 1 + if self.recursions == 0: + self.in_thread = None + self.lock.release() + + _importlock = _ImportLock() + + lock_held = _importlock.held + acquire_lock = _importlock.acquire + release_lock = _importlock.release + + import __builtin__ + _original_import_hook = __builtin__.__import__ + def __lockedimport__(modulename, globals=None, locals=None, fromlist=None): + acquire_lock() + try: + return _original_import_hook(modulename, globals, locals, fromlist) + finally: + release_lock() + __builtin__.__import__ = __lockedimport__ + del __builtin__ Modified: pypy/dist/pypy/module/thread/__init__.py ============================================================================== --- pypy/dist/pypy/module/thread/__init__.py (original) +++ pypy/dist/pypy/module/thread/__init__.py Wed Aug 24 13:33:02 2005 @@ -16,6 +16,7 @@ 'allocate': 'os_lock.allocate_lock', # obsolete synonym 'LockType': 'os_lock.getlocktype(space)', '_local': 'os_local.getlocaltype(space)', + '_please_provide_import_lock': '(space.w_True)', # for imp.py } def __init__(self, space, *args): @@ -26,3 +27,9 @@ space.threadlocals = gil.GILThreadLocals() space.threadlocals.setvalue(prev) space.threadlocals.enter_thread(space) # setup the main thread + + def setup_after_space_initialization(self): + # the import lock is in imp.py. Import it after the space is fully + # initialized. + from pypy.module.__builtin__.importing import importhook + importhook(self.space, 'imp') Added: pypy/dist/pypy/module/thread/test/test_import_lock.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/thread/test/test_import_lock.py Wed Aug 24 13:33:02 2005 @@ -0,0 +1,15 @@ +from pypy.module.thread.test.support import GenericTestThread + + +class AppTestThread(GenericTestThread): + + def test_import_lock(self): + import thread + done = [] + def f(): + from imghdr import testall + done.append(1) + for i in range(5): + thread.start_new_thread(f, ()) + self.waitfor(lambda: len(done) == 5) + assert len(done) == 5 Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Aug 24 13:33:02 2005 @@ -107,6 +107,9 @@ if self.options.oldstyle: self.enable_old_style_classes_as_default_metaclass() + # final setup + self.setup_builtin_modules() + def enable_old_style_classes_as_default_metaclass(self): self.setitem(self.builtin.w_dict, self.wrap('__metaclass__'), self.w_classobj) From pedronis at codespeak.net Wed Aug 24 13:52:31 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 24 Aug 2005 13:52:31 +0200 (CEST) Subject: [pypy-svn] r16365 - in pypy/dist/pypy/translator: c c/src c/test tool Message-ID: <20050824115231.6353327B41@code1.codespeak.net> Author: pedronis Date: Wed Aug 24 13:52:27 2005 New Revision: 16365 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/src/exception.h pypy/dist/pypy/translator/c/src/mem.h pypy/dist/pypy/translator/c/test/test_boehm.py pypy/dist/pypy/translator/tool/cbuild.py Log: basic support for optionally using Boehm as the gc for RPython translated code (cfbolz, pedronis) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Wed Aug 24 13:52:27 2005 @@ -8,7 +8,6 @@ from pypy.translator.c.node import ContainerNodeFactory, ExtTypeOpaqueDefNode from pypy.translator.c.support import cdecl, CNameManager, ErrorValue from pypy.translator.c.pyobj import PyObjMaker -from pypy.translator.c import gc # ____________________________________________________________ @@ -25,6 +24,7 @@ if not standalone: self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator) if gcpolicy is None: + from pypy.translator.c import gc gcpolicy = gc.RefcountingGcPolicy self.gcpolicy = gcpolicy(self) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Wed Aug 24 13:52:27 2005 @@ -1,6 +1,8 @@ from pypy.translator.c.support import cdecl +from pypy.translator.c.node import ContainerNode from pypy.rpython.lltype import typeOf, Ptr, PyObject, ContainerType -from pypy.rpython.lltype import getRuntimeTypeInfo +from pypy.rpython.lltype import GcArray, GcStruct +from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo PyObjPtr = Ptr(PyObject) @@ -35,6 +37,44 @@ return self.pop_alive_nopyobj(expr, T) return '' + def push_alive_nopyobj(self, expr, T): + return '' + + def pop_alive_nopyobj(self, expr, T): + return '' + + def push_alive_op_result(self, opname, expr, T): + return '' + + def gcheader_field_name(self, defnode): + return None + + def common_gcheader_definition(self, defnode): + return [] + + def common_after_definition(self, defnode): + return [] + + def common_gcheader_initializationexpr(self, defnode): + return [] + + struct_gcheader_definition = common_gcheader_definition + struct_after_definition = common_after_definition + struct_gcheader_initialitionexpr = common_gcheader_initializationexpr + + def prepare_nested_gcstruct(self, structdefnode, INNER): + pass + + array_gcheader_definition = common_gcheader_definition + array_after_definition = common_after_definition + array_gcheader_initialitionexpr = common_gcheader_initializationexpr + + def gc_libraries(self): + return [] + + def pre_pre_gc_code(self): # code that goes before include g_prerequisite.h + return [] + def pre_gc_code(self): return [] @@ -114,8 +154,6 @@ for line in defnode.visitor_lines(prefix, self.generic_dealloc): yield line - - # for structs def prepare_nested_gcstruct(self, structdefnode, INNER): @@ -208,12 +246,8 @@ def rtti_type(self): return 'void (@)(void *)' # void dealloc_xx(struct xx *) - def rtti_node(self, defnode, node): - node.typename = 'void (@)(void *)' - node.implementationtypename = 'void (@)(struct %s *)' % ( - defnode.name,) - node.name = defnode.gcinfo.static_deallocator - node.ptrname = '((void (*)(void *)) %s)' % (node.name,) + def rtti_node_factory(self): + return RefcountingRuntimeTypeInfo_OpaqueNode # zero malloc impl @@ -222,4 +256,126 @@ eresult, err) +class RefcountingRuntimeTypeInfo_OpaqueNode(ContainerNode): + globalcontainer = True + includes = () + typename = 'void (@)(void *)' + + def __init__(self, db, T, obj): + assert T == RuntimeTypeInfo + assert isinstance(obj.about, GcStruct) + self.db = db + self.T = T + self.obj = obj + defnode = db.gettypedefnode(obj.about) + self.implementationtypename = 'void (@)(struct %s *)' % ( + defnode.name,) + self.name = defnode.gcinfo.static_deallocator + self.ptrname = '((void (*)(void *)) %s)' % (self.name,) + + def enum_dependencies(self): + return [] + + def implementation(self): + return [] + + + +class BoehmGcInfo: + finalizer = None + +class BoehmGcPolicy(BasicGcPolicy): + + write_barrier = RefcountingGcPolicy.write_barrier.im_func + + generic_dealloc = RefcountingGcPolicy.generic_dealloc.im_func + + deallocator_lines = RefcountingGcPolicy.deallocator_lines.im_func + + # for arrays + + def array_setup(self, arraydefnode): + if isinstance(arraydefnode.LLTYPE, GcArray) and list(self.deallocator_lines(arraydefnode, '')): + gcinfo = arraydefnode.gcinfo = RefcountingInfo() + gcinfo.finalizer = self.db.namespace.uniquename('finalize_'+arraydefnode.barename) + + def array_implementationcode(self, arraydefnode): + if arraydefnode.gcinfo: + gcinfo = arraydefnode.gcinfo + if gcinfo.finalizer: + yield 'void %s(GC_PTR obj, GC_PTR ignore) {' % (gcinfo.finalizer, arraydefnode.name) + yield '\tstruct %s *a = (struct %s *)obj;' % (arraydefnode.name, arraydefnode.name) + for line in self.deallocator_lines(arraydefnode, '(*a)'): + yield '\t' + line + yield '}' + + # for structs + def struct_setup(self, structdefnode, rtti): + if isinstance(structdefnode.LLTYPE, GcStruct) and list(self.deallocator_lines(structdefnode, '')): + gcinfo = structdefnode.gcinfo = RefcountingInfo() + gcinfo.finalizer = self.db.namespace.uniquename('finalize_'+structdefnode.barename) + + def struct_implementationcode(self, structdefnode): + if structdefnode.gcinfo: + gcinfo = structdefnode.gcinfo + if gcinfo.finalizer: + yield 'void %s(GC_PTR obj, GC_PTR ignore) {' % (gcinfo.finalizer, structdefnode.name) + yield '\tstruct %s *p = (struct %s *)obj;' % (structdefnode.name, structdefnode.name) + for line in self.deallocator_lines(structdefnode, '(*p)'): + yield '\t' + line + yield '}' + + # for rtti node + + def rtti_type(self): + return 'long @' + + def rtti_node_factory(self): + return BoehmGcRuntimeTypeInfo_OpaqueNode + + # zero malloc impl + + def zero_malloc(self, TYPE, esize, eresult, err): + gcinfo = self.db.gettypedefnode(TYPE).gcinfo + if gcinfo and gcinfo.finalizer: + yield 'OP_BOEHM_ZERO_MALLOC_FINALIZER(%s, %s, %s, %s);' % (esize, + eresult, + gcinfo.finalizer, + err) + else: + yield 'OP_BOEHM_ZERO_MALLOC(%s, %s, %s);' % (esize, + eresult, + err) + + def gc_libraries(self): + return ['gc'] # xxx on windows? + + def pre_pre_gc_code(self): + yield '#include ' + yield '#define USING_BOEHM_GC' + + def gc_startup_code(self): + yield 'GC_INIT();' + + +class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode): + globalcontainer = True + includes = () + typename = 'long @' + implementationtypename = typename + + def __init__(self, db, T, obj): + assert T == RuntimeTypeInfo + assert isinstance(obj.about, GcStruct) + self.db = db + self.T = T + self.obj = obj + defnode = db.gettypedefnode(obj.about) + self.name = self.db.namespace.uniquename('g_rtti_v_'+ defnode.barename) + self.ptrname = '&%s' % (self.name,) + + def enum_dependencies(self): + return [] + def implementation(self): + yield 'long %s = %d;' % (self.name, id(self.obj)) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Wed Aug 24 13:52:27 2005 @@ -16,15 +16,23 @@ _compiled = False symboltable = None - def __init__(self, translator, gcpolicy=None): + def __init__(self, translator, gcpolicy=None, libraries=None): self.translator = translator self.gcpolicy = gcpolicy - + + if libraries is None: + libraries = [] + self.libraries = libraries + def generate_source(self): assert self.c_source_filename is None translator = self.translator pf = self.getentrypointptr() db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicy=self.gcpolicy) + + # we need a concrete gcpolicy to do this + self.libraries += db.gcpolicy.gc_libraries() + pfname = db.get(pf) db.complete() @@ -59,7 +67,8 @@ assert not self._compiled compile_c_module(self.c_source_filename, self.c_source_filename.purebasename, - include_dirs = [autopath.this_dir]) + include_dirs = [autopath.this_dir], + libraries=self.libraries) self._compiled = True def import_module(self): @@ -95,7 +104,8 @@ python_inc = sysconfig.get_python_inc() self.executable_name = build_executable([self.c_source_filename], include_dirs = [autopath.this_dir, - python_inc]) + python_inc], + libraries=self.libraries) self._compiled = True return self.executable_name @@ -226,6 +236,10 @@ # for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) + + for line in database.gcpolicy.pre_pre_gc_code(): + print >> f, line + print >> f, '#include "src/g_prerequisite.h"' for line in database.gcpolicy.pre_gc_code(): Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Wed Aug 24 13:52:27 2005 @@ -53,7 +53,10 @@ assert isinstance(T, GC_CONTAINER) firstdefnode = db.gettypedefnode(T) firstfieldname = self.c_struct_field_name(STRUCT._names[0]) - self.gcheader = '%s.%s' % (firstfieldname, firstdefnode.gcheader) + if firstdefnode.gcheader: + self.gcheader = '%s.%s' % (firstfieldname, firstdefnode.gcheader) + else: + self.gcheader = None # give the gcpolicy a chance to do sanity checking or special preparation for # this case @@ -507,28 +510,6 @@ else: raise ValueError, "don't know how to generate code for %r" % (fnobj,) -# xxx move it completly to the gcpolicy -class RuntimeTypeInfo_OpaqueNode(ContainerNode): - globalcontainer = True - includes = () - - def __init__(self, db, T, obj): - assert T == RuntimeTypeInfo - assert isinstance(obj.about, GcStruct) - self.db = db - self.T = T - self.obj = obj - defnode = db.gettypedefnode(obj.about) - - self.db.gcpolicy.rtti_node(defnode, self) - - def enum_dependencies(self): - return [] - - def implementation(self): - return [] - - class ExtType_OpaqueNode(ContainerNode): def enum_dependencies(self): @@ -551,7 +532,7 @@ def opaquenode_factory(db, T, obj): if T == RuntimeTypeInfo: - return RuntimeTypeInfo_OpaqueNode(db, T, obj) + return db.gcpolicy.rtti_node_factory()(db, T, obj) if hasattr(T, '_exttypeinfo'): return ExtType_OpaqueNode(db, T, obj) raise Exception("don't know about %r" % (T,)) Modified: pypy/dist/pypy/translator/c/src/exception.h ============================================================================== --- pypy/dist/pypy/translator/c/src/exception.h (original) +++ pypy/dist/pypy/translator/c/src/exception.h Wed Aug 24 13:52:27 2005 @@ -71,11 +71,11 @@ #define RPyRaiseSimpleException(exc, msg) \ - /* XXX 1. uses officially bad fishing */ \ - /* XXX 2. msg is ignored */ \ - rpython_exc_type = (R##exc)->o_typeptr; \ - rpython_exc_value = (R##exc); \ - rpython_exc_value->refcount++ + /* XXX 1. uses officially bad fishing */ \ + /* XXX 2. msg is ignored */ \ + rpython_exc_type = (R##exc)->o_typeptr; \ + rpython_exc_value = (R##exc); \ + PUSH_ALIVE(rpython_exc_value) /******************************************************************/ #else /* non-RPython version of exceptions, using CPython only */ Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Wed Aug 24 13:52:27 2005 @@ -17,6 +17,8 @@ #define OP_FREE(p) { PyObject_Free(p); COUNT_FREE; } +/* XXX uses officially bad fishing */ +#define PUSH_ALIVE(obj) obj->refcount++ /*------------------------------------------------------------*/ #ifndef COUNT_OP_MALLOCS @@ -42,3 +44,25 @@ /*------------------------------------------------------------*/ #endif /*COUNT_OP_MALLOCS*/ /*------------------------------------------------------------*/ + +/* for Boehm GC */ + +#ifdef USING_BOEHM_GC + +#define OP_BOEHM_ZERO_MALLOC(size, r, err) { \ + r = (void*) GC_MALLOC(size); \ + if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory"); \ + memset((void*) r, 0, size); \ + } + +#define OP_BOEHM_ZERO_MALLOC_FINALIZER(size, r, finalizer, err) { \ + r = (void*) GC_MALLOC(size); \ + if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory"); \ + GC_REGISTER_FINALIZER(r, finalizer, NULL, NULL, NULL); \ + memset((void*) r, 0, size); \ + } + +#undef PUSH_ALIVE +#define PUSH_ALIVE(obj) + +#endif /* USING_BOEHM_GC */ Modified: pypy/dist/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_boehm.py (original) +++ pypy/dist/pypy/translator/c/test/test_boehm.py Wed Aug 24 13:52:27 2005 @@ -1,41 +1,59 @@ +import py +test_src = """ from pypy.translator.translator import Translator from pypy.translator.tool.cbuild import skip_missing_compiler from pypy.translator.c.genc import CExtModuleBuilder -class TestBoehmTestCase: +def getcompiled(func): + from pypy.translator.c.gc import BoehmGcPolicy + t = Translator(func, simplifying=True) + # builds starting-types from func_defs + argstypelist = [] + if func.func_defaults: + for spec in func.func_defaults: + if isinstance(spec, tuple): + spec = spec[0] # use the first type only for the tests + argstypelist.append(spec) + a = t.annotate(argstypelist) + a.simplify() + t.specialize() + t.checkgraphs() + def compile(): + cbuilder = CExtModuleBuilder(t, gcpolicy=BoehmGcPolicy) + c_source_filename = cbuilder.generate_source() + cbuilder.compile() + cbuilder.import_module() + return cbuilder.get_entry_point() + return skip_missing_compiler(compile) + + +def test_malloc_a_lot(): + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = [1] * 10 + j = 0 + while j < 20: + j += 1 + a.append(j) + fn = getcompiled(malloc_a_lot) + fn() + +def run_test(fn): + fn() + channel.send(None) + +run_test(test_malloc_a_lot) +""" + + +def test_boehm(): + import py + gw = py.execnet.PopenGateway() + chan = gw.remote_exec(py.code.Source(test_src)) + res = chan.receive() + assert not res + chan.close() + - def getcompiled(self, func): - from pypy.translator.c.gc import BoehmGcPolicy - t = Translator(func, simplifying=True) - # builds starting-types from func_defs - argstypelist = [] - if func.func_defaults: - for spec in func.func_defaults: - if isinstance(spec, tuple): - spec = spec[0] # use the first type only for the tests - argstypelist.append(spec) - a = t.annotate(argstypelist) - a.simplify() - t.specialize() - t.checkgraphs() - def compile(): - cbuilder = CExtModuleBuilder(t, gcpolicy=BoehmGcPolicy) - c_source_filename = cbuilder.generate_source() - cbuilder.compile() - cbuilder.import_module() - return cbuilder.get_entry_point() - return skip_missing_compiler(compile) - - - def DONTtest_malloc_a_lot(self): - def malloc_a_lot(): - i = 0 - while i < 10: - i += 1 - a = [1] * 10 - j = 0 - while j < 20: - j += 1 - a.append(j) - fn = self.getcompiled(malloc_a_lot) - fn() Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Wed Aug 24 13:52:27 2005 @@ -36,7 +36,7 @@ opt = '-O0' gcv['OPT'] = opt -def compile_c_module(cfile, modname, include_dirs=None): +def compile_c_module(cfile, modname, include_dirs=None, libraries=[]): #try: # from distutils.log import set_threshold # set_threshold(10000) @@ -92,7 +92,8 @@ 'ext_modules': [ Extension(modname, [str(cfile)], include_dirs=include_dirs, - extra_compile_args=extra_compile_args) + extra_compile_args=extra_compile_args, + libraries=libraries,) ], 'script_name': 'setup.py', 'script_args': ['-q', 'build_ext', '--inplace'], From pedronis at codespeak.net Wed Aug 24 14:11:02 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 24 Aug 2005 14:11:02 +0200 (CEST) Subject: [pypy-svn] r16368 - in pypy/dist/pypy/translator: . goal Message-ID: <20050824121102.3C0E227B41@code1.codespeak.net> Author: pedronis Date: Wed Aug 24 14:11:00 2005 New Revision: 16368 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/translator.py Log: added an option -boehm to translate_pypy to use the Boehm collector with the translated RPython code. Don't try to not use -text with this option, loading pygame seems to result in a too many root sets problem (at least on Mac OS X). Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Wed Aug 24 14:11:00 2005 @@ -20,6 +20,7 @@ -fork (UNIX) Create a restartable checkpoint after annotation -llvm Use LLVM instead of C -c Generate the C code, but don't compile it + -boehm Use the Boehm collector when generating C code -o Generate and compile the C code, but don't run it -tcc Equivalent to the envvar PYPY_CC='tcc -shared -o "%s.so" "%s.c"' -- http://fabrice.bellard.free.fr/tcc/ @@ -331,6 +332,7 @@ options = {'-text': False, '-no-c': False, '-c': False, + '-boehm': False, '-o': False, '-llvm': False, '-no-mark-some-objects': False, @@ -610,6 +612,11 @@ ) if err: raise err[0], err[1], err[2] + gcpolicy = None + if options['-boehm']: + from pypy.translator.c import gc + gcpolicy = gc.BoehmGcPolicy + if options['-llinterpret']: def interpret(): import py @@ -629,7 +636,7 @@ else: print 'Generating C code without compiling it...' filename = t.ccompile(really_compile=False, - standalone=standalone) + standalone=standalone, gcpolicy=gcpolicy) update_usession_dir() print 'Written %s.' % (filename,) else: @@ -638,7 +645,7 @@ c_entry_point = t.llvmcompile(standalone=standalone) else: print 'Generating and compiling C code...' - c_entry_point = t.ccompile(standalone=standalone) + c_entry_point = t.ccompile(standalone=standalone, gcpolicy=gcpolicy) update_usession_dir() if not options['-o']: print 'Running!' Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Wed Aug 24 14:11:00 2005 @@ -252,13 +252,13 @@ mod = make_module_from_pyxstring(name, udir, pyxcode) return getattr(mod, name) - def ccompile(self, really_compile=True, standalone=False): + def ccompile(self, really_compile=True, standalone=False, gcpolicy=None): """Returns compiled function (living in a new C-extension module), compiled using the C generator. """ if self.annotator is not None: self.frozen = True - cbuilder = self.cbuilder(standalone=standalone) + cbuilder = self.cbuilder(standalone=standalone, gcpolicy=gcpolicy) c_source_filename = cbuilder.generate_source() if not really_compile: return c_source_filename @@ -268,12 +268,12 @@ cbuilder.import_module() return cbuilder.get_entry_point() - def cbuilder(self, standalone=False): + def cbuilder(self, standalone=False, gcpolicy=None): from pypy.translator.c import genc if standalone: - return genc.CStandaloneBuilder(self) + return genc.CStandaloneBuilder(self, gcpolicy=gcpolicy) else: - return genc.CExtModuleBuilder(self) + return genc.CExtModuleBuilder(self, gcpolicy=gcpolicy) def llvmcompile(self, really_compile=True, standalone=False, optimize=True): """llvmcompile(self, really_compile=True, standalone=False, optimize=True) -> LLVM translation From cfbolz at codespeak.net Wed Aug 24 14:21:00 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 24 Aug 2005 14:21:00 +0200 (CEST) Subject: [pypy-svn] r16369 - pypy/dist/pypy/objspace/std/test Message-ID: <20050824122100.76D6927B41@code1.codespeak.net> Author: cfbolz Date: Wed Aug 24 14:20:59 2005 New Revision: 16369 Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py Log: add failing test for float ** float Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_floatobject.py Wed Aug 24 14:20:59 2005 @@ -1,7 +1,7 @@ import autopath from pypy.objspace.std import floatobject as fobj from pypy.objspace.std.objspace import FailedToImplement - +import py class TestW_FloatObject: @@ -122,7 +122,11 @@ assert pw(-1.0, 2.0) == 1.0 assert pw(-1.0, 3.0) == -1.0 assert pw(-1.0, 1e200) == 1.0 - + + def DONOTtest_pow_neg_base(self): + def pw(x, y): + return x ** y + assert pw(-2.0, 2.0) == 4 From ale at codespeak.net Wed Aug 24 14:26:03 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 24 Aug 2005 14:26:03 +0200 (CEST) Subject: [pypy-svn] r16371 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050824122603.38A0527B41@code1.codespeak.net> Author: ale Date: Wed Aug 24 14:26:01 2005 New Revision: 16371 Modified: pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/test/test_floatobject.py Log: Added check for power of a negative number. Added the actual computation of pow(x,y) if x is negative (and passes the tests for negative numbers) Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Wed Aug 24 14:26:01 2005 @@ -314,13 +314,13 @@ return space.wrap(1.0) else: return space.wrap( -1.0) - else: - try: - z = math.pow(x,y) - except OverflowError: - raise FailedToImplement(space.w_OverflowError, space.wrap("float power")) - except ValueError: - raise FailedToImplement(space.w_ValueError, space.wrap("float power")) # xxx +# else: + try: + z = math.pow(x,y) + except OverflowError: + raise FailedToImplement(space.w_OverflowError, space.wrap("float power")) + except ValueError: + raise FailedToImplement(space.w_ValueError, space.wrap("float power")) # xxx return W_FloatObject(space, z) Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_floatobject.py Wed Aug 24 14:26:01 2005 @@ -37,6 +37,12 @@ self._unwrap_nonimpl(fobj.pow__Float_Float_ANY, self.space, f1, f2, self.space.w_None)) + x = -10 + y = 2.0 + f1 = fobj.W_FloatObject(self.space, x) + f2 = fobj.W_FloatObject(self.space, y) + v = fobj.pow__Float_Float_ANY(self.space, f1, f2, self.space.w_None) + assert v.floatval == x**y class AppTestAppFloatTest: def test_negatives(self): From arigo at codespeak.net Wed Aug 24 14:26:57 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 14:26:57 +0200 (CEST) Subject: [pypy-svn] r16372 - pypy/dist/pypy/lib/_stablecompiler Message-ID: <20050824122657.34CE727B47@code1.codespeak.net> Author: arigo Date: Wed Aug 24 14:26:56 2005 New Revision: 16372 Modified: pypy/dist/pypy/lib/_stablecompiler/consts.py pypy/dist/pypy/lib/_stablecompiler/pycodegen.py pypy/dist/pypy/lib/_stablecompiler/symbols.py Log: For now, revert mwh's patch that fixes exec "global a; a=1" in glob, loc This creates another problem shown by the following code: def g(): class X: def f(): print str def str(): print 5 return X g().str --> AttributeError This was reverted with svn merge -r15606:15605 . Modified: pypy/dist/pypy/lib/_stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/consts.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/consts.py Wed Aug 24 14:26:56 2005 @@ -8,7 +8,6 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 -SC_REALLY_GLOBAL = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Wed Aug 24 14:26:56 2005 @@ -10,7 +10,7 @@ from transformer import parse from visitor import walk import pyassem, misc, future, symbols -from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_REALLY_GLOBAL +from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL from consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pyassem import TupleArg @@ -287,8 +287,6 @@ self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) - elif scope == SC_REALLY_GLOBAL: - self.emit(prefix + '_GLOBAL', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) Modified: pypy/dist/pypy/lib/_stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/symbols.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/symbols.py Wed Aug 24 14:26:56 2005 @@ -1,8 +1,7 @@ """Module symbol-table generator""" import ast -from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, \ - SC_UNKNOWN, SC_REALLY_GLOBAL +from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_UNKNOWN from misc import mangle import types @@ -90,7 +89,7 @@ The scope of a name could be LOCAL, GLOBAL, FREE, or CELL. """ if self.globals.has_key(name): - return SC_REALLY_GLOBAL + return SC_GLOBAL if self.cells.has_key(name): return SC_CELL if self.defs.has_key(name): @@ -155,7 +154,7 @@ if sc == SC_UNKNOWN or sc == SC_FREE \ or isinstance(self, ClassScope): self.frees[name] = 1 - elif sc == SC_GLOBAL or sc == SC_REALLY_GLOBAL: + elif sc == SC_GLOBAL: child_globals.append(name) elif isinstance(self, FunctionScope) and sc == SC_LOCAL: self.cells[name] = 1 From ac at codespeak.net Wed Aug 24 14:30:17 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 14:30:17 +0200 (CEST) Subject: [pypy-svn] r16373 - pypy/dist/lib-python Message-ID: <20050824123017.35EAD27B41@code1.codespeak.net> Author: ac Date: Wed Aug 24 14:30:17 2005 New Revision: 16373 Modified: pypy/dist/lib-python/failure_list.txt Log: Add analysis of test_trace Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Wed Aug 24 14:30:17 2005 @@ -92,3 +92,7 @@ test_traceback test_nocaret fails because the examined SyntaxError doesn't carry a line number + +test_trace + Fails because of our compiler generating different linenumber information + than CPythons. From hpk at codespeak.net Wed Aug 24 14:31:47 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 24 Aug 2005 14:31:47 +0200 (CEST) Subject: [pypy-svn] r16374 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20050824123147.AAECE27B41@code1.codespeak.net> Author: hpk Date: Wed Aug 24 14:31:47 2005 New Revision: 16374 Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/symbols.py Log: revert the other part of mwh's fix in our second compiler copy Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/consts.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/consts.py Wed Aug 24 14:31:47 2005 @@ -8,7 +8,6 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 -SC_REALLY_GLOBAL = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Wed Aug 24 14:31:47 2005 @@ -9,7 +9,7 @@ from pypy.interpreter.stablecompiler import ast, parse, walk, syntax from pypy.interpreter.stablecompiler import pyassem, misc, future, symbols from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL, SC_REALLY_GLOBAL + SC_FREE, SC_CELL from pypy.interpreter.stablecompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pypy.interpreter.stablecompiler.pyassem import TupleArg @@ -286,8 +286,6 @@ self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) - elif scope == SC_REALLY_GLOBAL: - self.emit(prefix + '_GLOBAL', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py Wed Aug 24 14:31:47 2005 @@ -2,7 +2,7 @@ from pypy.interpreter.stablecompiler import ast from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL, SC_UNKNOWN, SC_REALLY_GLOBAL + SC_FREE, SC_CELL, SC_UNKNOWN from pypy.interpreter.stablecompiler.misc import mangle import types @@ -90,7 +90,7 @@ The scope of a name could be LOCAL, GLOBAL, FREE, or CELL. """ if self.globals.has_key(name): - return SC_REALLY_GLOBAL + return SC_GLOBAL if self.cells.has_key(name): return SC_CELL if self.defs.has_key(name): @@ -155,7 +155,7 @@ if sc == SC_UNKNOWN or sc == SC_FREE \ or isinstance(self, ClassScope): self.frees[name] = 1 - elif sc == SC_GLOBAL or sc == SC_REALLY_GLOBAL: + elif sc == SC_GLOBAL: child_globals.append(name) elif isinstance(self, FunctionScope) and sc == SC_LOCAL: self.cells[name] = 1 From cfbolz at codespeak.net Wed Aug 24 14:38:07 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 24 Aug 2005 14:38:07 +0200 (CEST) Subject: [pypy-svn] r16375 - pypy/dist/pypy/objspace/std/test Message-ID: <20050824123807.4DCC927B41@code1.codespeak.net> Author: cfbolz Date: Wed Aug 24 14:38:06 2005 New Revision: 16375 Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py Log: enable test, passes because of ale's fix Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_floatobject.py Wed Aug 24 14:38:06 2005 @@ -129,7 +129,7 @@ assert pw(-1.0, 3.0) == -1.0 assert pw(-1.0, 1e200) == 1.0 - def DONOTtest_pow_neg_base(self): + def test_pow_neg_base(self): def pw(x, y): return x ** y assert pw(-2.0, 2.0) == 4 From pedronis at codespeak.net Wed Aug 24 14:39:18 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 24 Aug 2005 14:39:18 +0200 (CEST) Subject: [pypy-svn] r16376 - pypy/dist/lib-python Message-ID: <20050824123918.E85F027B41@code1.codespeak.net> Author: pedronis Date: Wed Aug 24 14:39:18 2005 New Revision: 16376 Modified: pypy/dist/lib-python/conftest.py Log: test_gc is implementation depedent because so are the details of gc module behavior or presence => not core Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 14:39:18 2005 @@ -475,7 +475,7 @@ RegrTest('test_future1.py', enabled=True, dumbtest=1, core=True), RegrTest('test_future2.py', enabled=True, dumbtest=1, core=True), RegrTest('test_future3.py', enabled=True, core=True), - RegrTest('test_gc.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_gc.py', enabled=True, dumbtest=1), RegrTest('test_gdbm.py', enabled=False, dumbtest=1), RegrTest('test_generators.py', enabled=True, core=True), #rev 10840: 30 of 152 tests fail From nik at codespeak.net Wed Aug 24 15:16:40 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 24 Aug 2005 15:16:40 +0200 (CEST) Subject: [pypy-svn] r16379 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050824131640.AAD4C27B41@code1.codespeak.net> Author: nik Date: Wed Aug 24 15:16:39 2005 New Revision: 16379 Added: pypy/dist/lib-python/modified-2.4.1/test/test_repr.py - copied, changed from r16335, pypy/dist/lib-python/2.4.1/test/test_repr.py Log: changed/disabled too CPython-specific repr tests. test_repr passes now. From arigo at codespeak.net Wed Aug 24 15:23:48 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 15:23:48 +0200 (CEST) Subject: [pypy-svn] r16381 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050824132348.2571327B41@code1.codespeak.net> Author: arigo Date: Wed Aug 24 15:23:46 2005 New Revision: 16381 Modified: pypy/dist/pypy/objspace/std/dictobject.py pypy/dist/pypy/objspace/std/test/test_dictobject.py Log: Test for str(a_dict) when a_dict is mutated by the repr() of its content. Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Wed Aug 24 15:23:46 2005 @@ -290,7 +290,10 @@ currently_in_repr[dict_id] = 1 try: items = [] - for k, v in d.iteritems(): + # XXX for now, we cannot use iteritems() at app-level because + # we want a reasonable result instead of a RuntimeError + # even if the dict is mutated by the repr() in the loop. + for k, v in d.items(): items.append(repr(k) + ": " + repr(v)) return "{" + ', '.join(items) + "}" finally: Modified: pypy/dist/pypy/objspace/std/test/test_dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_dictobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_dictobject.py Wed Aug 24 15:23:46 2005 @@ -294,7 +294,15 @@ d[0] = d assert str(d) == '{0: {...}}' - + # Mutating while repr'ing + class Machiavelli: + def __repr__(self): + d.clear() + return "42" + d = {Machiavelli(): True} + str(d) + assert d == {} + def test_new(self): d = dict() assert d == {} From arigo at codespeak.net Wed Aug 24 15:35:45 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 15:35:45 +0200 (CEST) Subject: [pypy-svn] r16383 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20050824133545.E1AA927B41@code1.codespeak.net> Author: arigo Date: Wed Aug 24 15:35:44 2005 New Revision: 16383 Modified: pypy/dist/pypy/module/__builtin__/importing.py pypy/dist/pypy/module/__builtin__/test/test_import.py Log: * don't crash when there are empty .pyc files around. Added test. * re-enabled the .pyc file tests -- pyc file support was re-enabled some time ago already. Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Wed Aug 24 15:35:44 2005 @@ -378,10 +378,13 @@ # difficulties of using it though applevel. _r_correction = intmask(1L<<32) # == 0 on 32-bit machines def _r_long(osfile): - a = ord(osfile.read(1)) - b = ord(osfile.read(1)) - c = ord(osfile.read(1)) - d = ord(osfile.read(1)) + s = osfile.read(4) + if len(s) < 4: + return -1 # good enough for our purposes + a = ord(s[0]) + b = ord(s[1]) + c = ord(s[2]) + d = ord(s[3]) x = a | (b<<8) | (c<<16) | (d<<24) if _r_correction and d & 0x80 and x > 0: x -= _r_correction Modified: pypy/dist/pypy/module/__builtin__/test/test_import.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_import.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_import.py Wed Aug 24 15:35:44 2005 @@ -196,7 +196,6 @@ # ___________________ .pyc related stuff _________________ def test_check_compiled_module(self): - py.test.skip('pyc file support disabled for now') space = self.space pathname = "whatever" mtime = 12345 @@ -222,10 +221,18 @@ mtime, cpathname) assert ret == -1 + + # check for empty .pyc file + f = open(cpathname, 'wb') + f.close() + ret = importing.check_compiled_module(space, + pathname, + mtime, + cpathname) + assert ret == -1 os.remove(cpathname) def test_read_compiled_module(self): - py.test.skip('pyc file support disabled for now') space = self.space pathname = "whatever" mtime = 12345 @@ -244,7 +251,6 @@ assert ret == 42 def test_load_compiled_module(self): - py.test.skip('pyc file support disabled for now') space = self.space pathname = "whatever" mtime = 12345 @@ -316,7 +322,6 @@ #XXX Note tested while no writing def test_write_compiled_module(self): - py.test.skip('pyc file support disabled for now') space = self.space pathname = _testfilesource() fd = os.open(pathname, importing.BIN_READMASK, 0777) From ludal at codespeak.net Wed Aug 24 15:46:17 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Wed, 24 Aug 2005 15:46:17 +0200 (CEST) Subject: [pypy-svn] r16385 - in pypy/dist/pypy/interpreter/pyparser/test: . samples Message-ID: <20050824134617.795EB27B41@code1.codespeak.net> Author: ludal Date: Wed Aug 24 15:46:15 2005 New Revision: 16385 Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_transformer_bug.py Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_docstring.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - a bug in transformer.py drops statement after a docstring like that : """hello""";print 1 - astbuilder works correctly so we just add some test cases to remember the bug - also fix a bug in test_astbuilder recursive comparison of ast trees Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_docstring.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_docstring.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_docstring.py Wed Aug 24 15:46:15 2005 @@ -14,4 +14,7 @@ def foo(self): """function docstring""" +def boo(x): + """Docstring""";print 1 + """world""" Added: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_transformer_bug.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_transformer_bug.py Wed Aug 24 15:46:15 2005 @@ -0,0 +1,2 @@ +"""This module does nothing""";print 1 + Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Wed Aug 24 15:46:15 2005 @@ -54,9 +54,21 @@ del right_nodes[0] if not arglist_equal(left_args, right_args): return False + elif isinstance(left,stable_ast.Const): + if isinstance(right,ast_ast.NoneConst): + return left.value == None + elif isinstance(right, ast_ast.NumberConst): + return left.value == right.number_value + elif isinstance(right, ast_ast.StringConst): + return left.value == right.string_value + else: + print "Not const type %s" % repr(right) + return False else: left_nodes = left.getChildren() right_nodes = right.getChildren() + if len(left_nodes)!=len(right_nodes): + return False for i,j in zip(left_nodes,right_nodes): if not nodes_equal(i,j): return False @@ -384,7 +396,12 @@ a = 1 """bar""" return a - ''' + ''', + '''def foo(): + """doc"""; print 1 + a=1 + ''', + '''"""Docstring""";print 1''', ] returns = [ From ac at codespeak.net Wed Aug 24 15:53:08 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 15:53:08 +0200 (CEST) Subject: [pypy-svn] r16386 - pypy/dist/lib-python Message-ID: <20050824135308.5850927B41@code1.codespeak.net> Author: ac Date: Wed Aug 24 15:53:08 2005 New Revision: 16386 Modified: pypy/dist/lib-python/conftest.py pypy/dist/lib-python/failure_list.txt Log: More analysis. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 15:53:08 2005 @@ -577,7 +577,7 @@ # XXX this test is _also_ an output test, damn it # seems to be the only one that invokes run_unittest # and is an unittest - RegrTest('test_pep292.py', enabled=True, core=True), + RegrTest('test_pep292.py', enabled=True), RegrTest('test_pickle.py', enabled=True, core=True), RegrTest('test_pickletools.py', enabled=True, dumbtest=1, core=True), RegrTest('test_pkg.py', enabled=True, core=True), Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Wed Aug 24 15:53:08 2005 @@ -96,3 +96,6 @@ test_trace Fails because of our compiler generating different linenumber information than CPythons. + +test_pep292 + Depends on a working re module. From ac at codespeak.net Wed Aug 24 16:35:15 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 16:35:15 +0200 (CEST) Subject: [pypy-svn] r16389 - pypy/dist/lib-python Message-ID: <20050824143515.EDA1C27B3F@code1.codespeak.net> Author: ac Date: Wed Aug 24 16:35:14 2005 New Revision: 16389 Modified: pypy/dist/lib-python/conftest.py Log: More tests demoted from core. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 16:35:14 2005 @@ -444,10 +444,10 @@ RegrTest('test_difflib.py', enabled=True, dumbtest=1), RegrTest('test_dircache.py', enabled=True, core=True), RegrTest('test_dis.py', enabled=True), - RegrTest('test_distutils.py', enabled=True, core=True), + RegrTest('test_distutils.py', enabled=True), RegrTest('test_dl.py', enabled=False, dumbtest=1), - RegrTest('test_doctest.py', usemodules="thread", enabled=True, core=True), - RegrTest('test_doctest2.py', enabled=True, core=True), + RegrTest('test_doctest.py', usemodules="thread", enabled=True), + RegrTest('test_doctest2.py', enabled=True), RegrTest('test_dumbdbm.py', enabled=True), RegrTest('test_dummy_thread.py', enabled=True, core=True), RegrTest('test_dummy_threading.py', enabled=True, dumbtest=1, core=True), @@ -516,7 +516,7 @@ RegrTest('test_imp.py', enabled=True, core=True), RegrTest('test_import.py', enabled=True, dumbtest=1, core=True), RegrTest('test_importhooks.py', enabled=True, core=True), - RegrTest('test_inspect.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_inspect.py', enabled=True, dumbtest=1), RegrTest('test_ioctl.py', enabled=False), RegrTest('test_isinstance.py', enabled=True, core=True), RegrTest('test_iter.py', enabled=True, core=True, uselibfile=True), From arigo at codespeak.net Wed Aug 24 16:37:26 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 16:37:26 +0200 (CEST) Subject: [pypy-svn] r16390 - in pypy/dist/pypy/lib: . test2 Message-ID: <20050824143726.2BF0C27B3F@code1.codespeak.net> Author: arigo Date: Wed Aug 24 16:37:24 2005 New Revision: 16390 Modified: pypy/dist/pypy/lib/imp.py pypy/dist/pypy/lib/test2/test_imp_extra.py Log: Completed and documented the 'imp' module. (May allow test_inspect to progress further.) Modified: pypy/dist/pypy/lib/imp.py ============================================================================== --- pypy/dist/pypy/lib/imp.py (original) +++ pypy/dist/pypy/lib/imp.py Wed Aug 24 16:37:24 2005 @@ -1,6 +1,6 @@ """ This module provides the components needed to build your own -__import__ function. Undocumented functions are obsolete. +__import__ function. """ # XXX partial implementation @@ -17,13 +17,23 @@ PY_CODERESOURCE = 8 def get_magic(): - return '\x3b\xf2\x0d\x0a' + """Return the magic number for .pyc or .pyo files.""" + return 'm\xf2\r\n' # XXX hard-coded: the magic of Python 2.4.1 def get_suffixes(): - return [('.py', 'U', PY_SOURCE)] + """Return a list of (suffix, mode, type) tuples describing the files + that find_module() looks for.""" + return [('.py', 'U', PY_SOURCE), + ('.pyc', 'rb', PY_COMPILED)] def find_module(name, path=None): + """find_module(name, [path]) -> (file, filename, (suffix, mode, type)) + Search for a module. If path is omitted or None, search for a + built-in, frozen or special module and continue search in sys.path. + The module name cannot contain '.'; to search for a submodule of a + package, pass the submodule name and the package's __path__. + """ import sys, os if path is None: if name in sys.builtin_module_names: @@ -40,26 +50,18 @@ def load_module(name, file, filename, description): + """Load a module, given information returned by find_module(). + The module name must include the full package name, if any. + """ import sys, os - new_module = type(sys) suffix, mode, type = description - module = sys.modules.get(name) if type == PY_SOURCE: - source = file.read() - co = compile(source, filename, 'exec') - if module is None: - sys.modules[name] = module = new_module(name) - module.__name__ = name - module.__doc__ = None - module.__file__ = filename - exec co in module.__dict__ - return module + return load_source(name, filename, file) if type == PKG_DIRECTORY: initfilename = os.path.join(filename, '__init__.py') - if module is None: - sys.modules[name] = module = new_module(name) + module = sys.modules.setdefault(name, new_module(name)) module.__name__ = name module.__doc__ = None module.__file__ = initfilename @@ -73,6 +75,74 @@ raise ValueError, 'invalid description argument: %r' % (description,) +def load_source(name, pathname, file=None): + import sys + autoopen = file is None + if autoopen: + file = open(pathname, 'U') + source = file.read() + if autoopen: + file.close() + co = compile(source, pathname, 'exec') + module = sys.modules.setdefault(name, new_module(name)) + module.__name__ = name + module.__doc__ = None + module.__file__ = pathname + exec co in module.__dict__ + return module + +def load_compiled(name, pathname, file=None): + import sys, marshal + autoopen = file is None + if autoopen: + file = open(pathname, 'rb') + magic = file.read(4) + if magic != get_magic(): + raise ImportError("Bad magic number in %s" % pathname) + file.read(4) # skip timestamp + co = marshal.load(file) + if autoopen: + file.close() + module = sys.modules.setdefault(name, new_module(name)) + module.__name__ = name + module.__doc__ = None + module.__file__ = pathname + exec co in module.__dict__ + return module + + +def new_module(name): + """Create a new module. Do not enter it in sys.modules. + The module name must include the full package name, if any. + """ + import new + return new.module(name) + + +def init_builtin(name): + import sys + if name not in sys.builtin_module_names: + return None + if name in sys.modules: + raise ImportError("cannot initialize a built-in module twice " + "in PyPy") + return __import__(name) + +def init_frozen(name): + return None + +def is_builtin(name): + import sys + if name in sys.builtin_module_names: + return -1 # cannot be initialized again + else: + return 0 + +def is_frozen(name): + return False + + +# ____________________________________________________________ try: # PyPy-specific interface: hint from the thread module to ask us to @@ -80,11 +150,13 @@ from thread import _please_provide_import_lock except ImportError: def lock_held(): + """On platforms without threads, return False.""" return False def acquire_lock(): - pass + """On platforms without threads, this function does nothing.""" def release_lock(): - pass + """On platforms without threads, this function does nothing.""" + else: del _please_provide_import_lock import thread @@ -96,9 +168,14 @@ self.recursions = 0 def held(self): + """Return True if the import lock is currently held, else False.""" return self.in_thread is not None def acquire(self): + """Acquires the interpreter's import lock for the current thread. + This lock should be used by import hooks to ensure thread-safety + when importing modules. + """ myident = thread.get_ident() if self.in_thread == myident: self.recursions += 1 @@ -108,6 +185,7 @@ self.recursions = 1 def release(self): + """Release the interpreter's import lock.""" myident = thread.get_ident() if self.in_thread != myident: raise RuntimeError("not holding the import lock") Modified: pypy/dist/pypy/lib/test2/test_imp_extra.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_imp_extra.py (original) +++ pypy/dist/pypy/lib/test2/test_imp_extra.py Wed Aug 24 16:37:24 2005 @@ -1,4 +1,3 @@ - from pypy.lib import imp import os @@ -21,3 +20,77 @@ elif mode == imp.PY_COMPILED: assert suffix in ('.pyc', '.pyo') assert type == 'rb' + + +def test_obscure_functions(): + mod = imp.new_module('hi') + assert mod.__name__ == 'hi' + mod = imp.init_builtin('hello.world.this.is.never.a.builtin.module.name') + assert mod is None + mod = imp.init_frozen('hello.world.this.is.never.a.frozen.module.name') + assert mod is None + assert imp.is_builtin('sys') + assert not imp.is_builtin('hello.world.this.is.never.a.builtin.module.name') + assert not imp.is_frozen('hello.world.this.is.never.a.frozen.module.name') + + +MARKER = 42 + +def _pyc_file(): + # XXX quick hack + # (that's the bytecode for the module containing only 'marker=42') + f = open('@TEST.pyc', 'wb') + f.write('m\xf2\r\n\xd6\x85\x0cCc\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00' + '\x00\x00@\x00\x00\x00s\n\x00\x00\x00d\x00\x00Z\x00\x00d\x01\x00' + 'S(\x02\x00\x00\x00i*\x00\x00\x00N(\x01\x00\x00\x00t\x06\x00\x00' + '\x00marker(\x01\x00\x00\x00R\x00\x00\x00\x00(\x00\x00\x00\x00(' + '\x00\x00\x00\x00t\x04\x00\x00\x00x.pyt\x01\x00\x00\x00?\x01\x00' + '\x00\x00s\x00\x00\x00\x00') + f.close() + return '@TEST.pyc' + +def test_load_module_py(): + descr = ('.py', 'U', imp.PY_SOURCE) + f = open(__file__, 'U') + mod = imp.load_module('test_imp_extra_AUTO1', f, __file__, descr) + f.close() + assert mod.MARKER == 42 + import test_imp_extra_AUTO1 + assert mod is test_imp_extra_AUTO1 + +def test_load_module_pyc(): + fn = _pyc_file() + try: + descr = ('.pyc', 'rb', imp.PY_COMPILED) + f = open(fn, 'rb') + mod = 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(): + mod = imp.load_source('test_imp_extra_AUTO3', __file__) + assert mod.MARKER == 42 + import test_imp_extra_AUTO3 + assert mod is test_imp_extra_AUTO3 + +def test_load_module_pyc(): + fn = _pyc_file() + try: + mod = 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(): + try: + imp.load_compiled('test_imp_extra_AUTO5', __file__) + except ImportError: + pass + else: + raise Exception("expected an ImportError") From arigo at codespeak.net Wed Aug 24 16:39:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 16:39:44 +0200 (CEST) Subject: [pypy-svn] r16391 - pypy/dist/pypy/lib/test2 Message-ID: <20050824143944.9A44627B3F@code1.codespeak.net> Author: arigo Date: Wed Aug 24 16:39:43 2005 New Revision: 16391 Modified: pypy/dist/pypy/lib/test2/test_imp_extra.py Log: Oups, broken test (failed when run the second time, because of .pyc files around). Modified: pypy/dist/pypy/lib/test2/test_imp_extra.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_imp_extra.py (original) +++ pypy/dist/pypy/lib/test2/test_imp_extra.py Wed Aug 24 16:39:43 2005 @@ -36,6 +36,13 @@ MARKER = 42 +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 + def _pyc_file(): # XXX quick hack # (that's the bytecode for the module containing only 'marker=42') @@ -50,9 +57,10 @@ return '@TEST.pyc' def test_load_module_py(): + fn = _py_file() descr = ('.py', 'U', imp.PY_SOURCE) - f = open(__file__, 'U') - mod = imp.load_module('test_imp_extra_AUTO1', f, __file__, descr) + f = open(fn, 'U') + mod = imp.load_module('test_imp_extra_AUTO1', f, fn, descr) f.close() assert mod.MARKER == 42 import test_imp_extra_AUTO1 @@ -72,7 +80,8 @@ os.unlink(fn) def test_load_source(): - mod = imp.load_source('test_imp_extra_AUTO3', __file__) + fn = _py_file() + mod = imp.load_source('test_imp_extra_AUTO3', fn) assert mod.MARKER == 42 import test_imp_extra_AUTO3 assert mod is test_imp_extra_AUTO3 @@ -88,8 +97,9 @@ os.unlink(fn) def test_load_broken_pyc(): + fn = _py_file() try: - imp.load_compiled('test_imp_extra_AUTO5', __file__) + imp.load_compiled('test_imp_extra_AUTO5', fn) except ImportError: pass else: From arigo at codespeak.net Wed Aug 24 16:49:25 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 16:49:25 +0200 (CEST) Subject: [pypy-svn] r16395 - pypy/dist/lib-python Message-ID: <20050824144925.A3ACA27B3F@code1.codespeak.net> Author: arigo Date: Wed Aug 24 16:49:24 2005 New Revision: 16395 Modified: pypy/dist/lib-python/failure_list.txt Log: Removed FIXED tests from failure_list (they are indeed fixed in the test report page now). Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Wed Aug 24 16:49:24 2005 @@ -20,11 +20,6 @@ multiple tests fail because from __future__ import division does not work (true division is never enabled) - -test_iterlen (ale will work on this) FIXED (finally) - - fails because len is not implemented for SeqIter (and - other structures like generators (reversed) ) test_compiler fails because of "maximum recursion depth exceeded" @@ -32,8 +27,6 @@ test_decorator fails because globals and locals are None in a nested function ? -test_enumerate FIXED by skippiing a test for an implementation detail . - test_builtin - our compilers need to recognize BOM markers - eval etc should accept dict subclasses @@ -54,22 +47,10 @@ test_tuple etc do we want to support x is x*1 where x is exactly a tuple? -test_new FIXED - test_extcall cannot be fixed. PyPy produces different TypeError messages but they are also correct and useful (reviewed them again). -test_optparse FIXED - - -test_sort FIXED - different way of detecting mutations during sort: PyPy didn't detect - changes done by the __del__ method of the key-wrapper objects. - -test_str FIXED - there's some optimisation tests failing => disabled them - test_tempfile still failing @@ -79,11 +60,7 @@ test_cpickle test_descr - FIXED? should be re-run. Were fixed in modified-2.3.4, but then they - were somehow lost when we switched to 2.4.1... - -test_sys (FIXED) - refcount test disabled (considered implementation detail from CPython) + have been re-run, still failing test_multibytecodec needs the gb18030 codec, part of the CJK codecs. either remove this test From ac at codespeak.net Wed Aug 24 17:27:05 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 17:27:05 +0200 (CEST) Subject: [pypy-svn] r16397 - pypy/dist/lib-python Message-ID: <20050824152705.D499D27B41@code1.codespeak.net> Author: ac Date: Wed Aug 24 17:27:05 2005 New Revision: 16397 Modified: pypy/dist/lib-python/conftest.py Log: More demoted tests. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 17:27:05 2005 @@ -719,9 +719,9 @@ RegrTest('test_urllibnet.py', enabled=False), # try to understand failure!!! RegrTest('test_urlparse.py', enabled=True), - RegrTest('test_userdict.py', enabled=True, core=True), - RegrTest('test_userlist.py', enabled=True, core=True), - RegrTest('test_userstring.py', enabled=True, core=True), + RegrTest('test_userdict.py', enabled=True), + RegrTest('test_userlist.py', enabled=True), + RegrTest('test_userstring.py', enabled=True), RegrTest('test_uu.py', enabled=False), #rev 10840: 1 of 9 test fails From jacob at codespeak.net Wed Aug 24 17:28:00 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Wed, 24 Aug 2005 17:28:00 +0200 (CEST) Subject: [pypy-svn] r16398 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050824152800.17DB727B4E@code1.codespeak.net> Author: jacob Date: Wed Aug 24 17:27:58 2005 New Revision: 16398 Added: pypy/dist/lib-python/modified-2.4.1/test/test_quopri.py - copied unchanged from r16396, pypy/dist/lib-python/2.4.1/test/test_quopri.py Log: Need to remove implementation specific test. From ac at codespeak.net Wed Aug 24 17:37:56 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 17:37:56 +0200 (CEST) Subject: [pypy-svn] r16401 - pypy/dist/lib-python Message-ID: <20050824153756.B90E627B50@code1.codespeak.net> Author: ac Date: Wed Aug 24 17:37:56 2005 New Revision: 16401 Modified: pypy/dist/lib-python/conftest.py Log: Demote test_pep263 Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 17:37:56 2005 @@ -572,7 +572,7 @@ RegrTest('test_peepholer.py', enabled=True), RegrTest('test_pep247.py', enabled=False, dumbtest=1), - RegrTest('test_pep263.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_pep263.py', enabled=True, dumbtest=1), RegrTest('test_pep277.py', enabled=False), # XXX this test is _also_ an output test, damn it # seems to be the only one that invokes run_unittest From arigo at codespeak.net Wed Aug 24 17:57:53 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 17:57:53 +0200 (CEST) Subject: [pypy-svn] r16403 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050824155753.803A427B53@code1.codespeak.net> Author: arigo Date: Wed Aug 24 17:57:51 2005 New Revision: 16403 Modified: pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/test/test_floatobject.py Log: (cfbolz, arigo) fixed comparison between floats and longs, for the case where the longs are larger than fits in a float. Slightly naive approach. Needs to review the complex CPython logic at some point... Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Wed Aug 24 17:57:51 2005 @@ -2,6 +2,7 @@ from pypy.interpreter import gateway from pypy.objspace.std.noneobject import W_NoneObject from pypy.objspace.std.longobject import W_LongObject, _AsDouble, _FromDouble +from pypy.objspace.std.longobject import isinf from pypy.rpython.rarithmetic import ovfcheck_float_to_int, intmask ############################################################## @@ -125,6 +126,67 @@ j = w_float2.floatval return space.newbool( i >= j ) +# 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 loose 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 = _FromDouble(space, 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 = _FromDouble(space, 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 + else: + return space.eq(w_float1, w_long2) + +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 gt__Long_Float(space, w_long1, w_float2): + return lt__Float_Long(space, w_float2, w_long1) + +def ge__Float_Long(space, w_float1, w_long2): + return space.not_(lt__Float_Long(space, w_float1, w_long2)) + +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/dist/pypy/objspace/std/test/test_floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_floatobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_floatobject.py Wed Aug 24 17:57:51 2005 @@ -134,5 +134,45 @@ return x ** y assert pw(-2.0, 2.0) == 4 - - + def test_float_cmp(self): + assert 12.5 == 12.5 + assert 12.5 != -3.2 + assert 12.5 < 123.4 + assert .25 <= .25 + assert -5744.23 <= -51.2 + assert 4.3 > 2.3 + assert 0.01 >= -0.01 + # float+long + verylonglong = 10L**400 + infinite = 1e200*1e200 + assert 12.0 == 12L + assert 1e300 == long(1e300) + assert 12.1 != 12L + assert infinite != 123456789L + assert 12.9 < 13L + assert -infinite < -13L + assert 12.9 <= 13L + assert 13.0 <= 13L + assert 13.01 > 13L + assert 13.0 >= 13L + assert 13.01 >= 13L + assert infinite > verylonglong + assert infinite >= verylonglong + assert 1234.56 < verylonglong + assert 1234.56 <= verylonglong + # long+float + assert 12L == 12.0 + assert long(1e300) == 1e300 + assert 12L != 12.1 + assert 123456789L != infinite + assert 13L > 12.9 + assert -13L > -infinite + assert 13L >= 12.9 + assert 13L >= 13.0 + assert 13L < 13.01 + assert 13L <= 13.0 + assert 13L <= 13.01 + assert verylonglong < infinite + assert verylonglong <= infinite + assert verylonglong > 1234.56 + assert verylonglong >= 1234.56 From nik at codespeak.net Wed Aug 24 18:02:19 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 24 Aug 2005 18:02:19 +0200 (CEST) Subject: [pypy-svn] r16405 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050824160219.E303427B55@code1.codespeak.net> Author: nik Date: Wed Aug 24 18:02:19 2005 New Revision: 16405 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_array.py Log: disabled one test for UCS-4 builds that passes in CPython because of a bug. test_array passes again. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_array.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_array.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_array.py Wed Aug 24 18:02:19 2005 @@ -733,6 +733,14 @@ self.assertRaises(TypeError, a.fromunicode) + def test_byteswap(self): + import sys + if sys.maxunicode > 0xffff: + return # Byteswapping results in invalid unicode characters for + # UCS-4 builds. That this works in CPython is really a + # bug. + StringTest.test_byteswap(self) + tests.append(UnicodeTest) class NumberTest(BaseTest): From ac at codespeak.net Wed Aug 24 18:12:43 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 18:12:43 +0200 (CEST) Subject: [pypy-svn] r16407 - pypy/dist/lib-python Message-ID: <20050824161243.831C027B57@code1.codespeak.net> Author: ac Date: Wed Aug 24 18:12:43 2005 New Revision: 16407 Modified: pypy/dist/lib-python/failure_list.txt Log: Do not mention passing tests. Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Wed Aug 24 18:12:43 2005 @@ -5,16 +5,6 @@ "can't assign to function call" instead of "can't delete function call". The test is for "delete" to be in the message -test_exceptions fails with exception message mismatches: - 'continue' not allowed inside 'finally' clause (, 5) - instead oof 'continue' not supported inside 'finally' clause - and - 'continue' outside loop (, 2) - instead of 'continue' not properly in loop - and - 'continue' outside loop (, 1) - instead of 'continue' not properly in loop - test_import fails because os.open is case insensitive (at least on Mac os X) @@ -54,10 +44,6 @@ test_tempfile still failing -test_exceptions - mismatch in SyntaxError messages - - test_cpickle test_descr have been re-run, still failing From arigo at codespeak.net Wed Aug 24 18:14:40 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 18:14:40 +0200 (CEST) Subject: [pypy-svn] r16408 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050824161440.54C0A27B58@code1.codespeak.net> Author: arigo Date: Wed Aug 24 18:14:38 2005 New Revision: 16408 Added: pypy/dist/lib-python/modified-2.4.1/test/test___all__.py - copied, changed from r16394, pypy/dist/lib-python/2.4.1/test/test___all__.py Log: (cfbolz, arigo) Hacked test___all__ to try to clean up sys.modules when an ImportError can leave broken semi-imported modules behind. From arigo at codespeak.net Wed Aug 24 18:20:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 18:20:29 +0200 (CEST) Subject: [pypy-svn] r16409 - pypy/dist/pypy/translator/c Message-ID: <20050824162029.E8ACF27B61@code1.codespeak.net> Author: arigo Date: Wed Aug 24 18:20:28 2005 New Revision: 16409 Modified: pypy/dist/pypy/translator/c/genc.py Log: (cfbolz, arigo) Added the GC-policy-specific header lines to the stand-alone source code too. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Wed Aug 24 18:20:28 2005 @@ -204,8 +204,15 @@ defines['PYPY_STANDALONE'] = entrypointname for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) + + for line in database.gcpolicy.pre_pre_gc_code(): + print >> f, line + print >> f, '#include "src/g_prerequisite.h"' + for line in database.gcpolicy.pre_gc_code(): + print >> f, line + preimplementationlines = list( pre_include_code_lines(database, database.translator.rtyper)) From tismer at codespeak.net Wed Aug 24 18:26:12 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 24 Aug 2005 18:26:12 +0200 (CEST) Subject: [pypy-svn] r16410 - in pypy/dist/pypy: module/math objspace/std rpython/module/test Message-ID: <20050824162612.3488B27B5A@code1.codespeak.net> Author: tismer Date: Wed Aug 24 18:26:08 2005 New Revision: 16410 Modified: pypy/dist/pypy/module/math/__init__.py pypy/dist/pypy/module/math/interp_math.py pypy/dist/pypy/objspace/std/longobject.py pypy/dist/pypy/rpython/module/test/test_ll_math.py Log: added a complete implementation of log/log10 Modified: pypy/dist/pypy/module/math/__init__.py ============================================================================== --- pypy/dist/pypy/module/math/__init__.py (original) +++ pypy/dist/pypy/module/math/__init__.py Wed Aug 24 18:26:08 2005 @@ -18,7 +18,6 @@ 'hypot' : 'interp_math.hypot', 'tan' : 'interp_math.tan', 'asin' : 'interp_math.asin', - 'log' : 'interp_math.log', 'fabs' : 'interp_math.fabs', 'floor' : 'interp_math.floor', 'sqrt' : 'interp_math.sqrt', Modified: pypy/dist/pypy/module/math/interp_math.py ============================================================================== --- pypy/dist/pypy/module/math/interp_math.py (original) +++ pypy/dist/pypy/module/math/interp_math.py Wed Aug 24 18:26:08 2005 @@ -2,6 +2,7 @@ import math from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped +from pypy.objspace.std import longobject class State: def __init__(self, space): @@ -44,9 +45,9 @@ raise OperationError(space.w_ValueError, space.wrap("math domain error")) return space.wrap(r) -math2._annspecialcase_ = 'specialize:arg1' +math2._annspecialcase_ = 'specialize:arg1' -def pow(space, x, y): +def pow(space, x, y): """pow(x,y) Return x**y (x to the power of y). @@ -92,18 +93,6 @@ return math1(space, math.asin, x) asin.unwrap_spec = [ObjSpace, float] -def log(space, x, w_base=NoneNotWrapped): - """log(x[, base]) -> the logarithm of x to the given base. - If the base not specified, returns the natural logarithm (base e) of x. - """ - num = math1_w(space, math.log, x) - if w_base is None: - return space.wrap(num) - else: - den = math1_w(space, math.log, space.float_w(w_base)) - return space.wrap(num / den) -log.unwrap_spec = [ObjSpace, float, W_Root] - def fabs(space, x): """fabs(x) @@ -148,11 +137,65 @@ return space.wrap(x / degToRad) degrees.unwrap_spec = [ObjSpace, float] -def log10(space, x): - """log10(x) -> the base 10 logarithm of x. +def _log_float(space, x, base): + if base == 10.0: + return math1(space, math.log10, x) + num = math1_w(space, math.log, x) + if base == 0.0: + return space.wrap(num) + else: + den = math1_w(space, math.log, base) + return space.wrap(num / den) + +def _log_any(space, w_x, base): + try: + x = space.float_w(w_x) + except OperationError: + pass + else: + return _log_float(space, x, base) + try: + w_x = space.long(w_x) + except OperationError: + raise OperationError(space.w_TypeError, space.wrap( + 'a float is required')) # yes, this message is as bad as CPython's + try: + if base == 10.0: + return space.wrap(longobject._loghelper(math.log10, w_x)) + ret = longobject._loghelper(math.log, w_x) + if base != 0.0: + ret /= math.log(base) + return space.wrap(ret) + except OverflowError: + raise OperationError(space.w_OverflowError, + space.wrap("math range error")) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("math domain error")) + +def log(space, w_x, w_base=NoneNotWrapped): + """log(x[, base]) -> the logarithm of x to the given base. + If the base not specified, returns the natural logarithm (base e) of x. """ - return math1(space, math.log10, x) -log10.unwrap_spec = [ObjSpace, float] + if w_base is None: + base = 0.0 + else: + try: + base = space.float_w(w_base) + except OperationError: + raise OperationError(space.w_TypeError, space.wrap( + 'a float is required')) + if base <= 0.0: + # just for raising the proper errors + return math1(space, math.log, base) + return _log_any(space, w_x, base) +log.unwrap_spec = [ObjSpace, W_Root, W_Root] + +def log10(space, w_x): + """log10(x) -> the base 10 logarithm of x. + """ + return _log_any(space, w_x, 10.0) +log10.unwrap_spec = [ObjSpace, W_Root] def fmod(space, x, y): """fmod(x,y) Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Wed Aug 24 18:26:08 2005 @@ -1260,6 +1260,7 @@ # note that math.ldexp checks for overflows, # while the C ldexp is not guaranteed to do. # XXX make sure that we don't ignore this! +# YYY no, we decided to do ignore this! def _AsDouble(v): """ Get a C double from a long int object. """ @@ -1271,6 +1272,23 @@ return x raise OverflowError # can't say "long int too large to convert to float" +def _loghelper(func, w_arg): + """ + A decent logarithm is easy to compute even for huge longs, but libm can't + do that by itself -- loghelper can. func is log or log10, and name is + "log" or "log10". Note that overflow isn't possible: a long can contain + no more than INT_MAX * SHIFT bits, so has value certainly less than + 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is + small enough to fit in an IEEE single. log and log10 are even smaller. + """ + x, e = _AsScaledDouble(w_arg); + # Value is ~= x * 2**(e*SHIFT), so the log ~= + # log(x) + log(2) * e * SHIFT. + # CAUTION: e*SHIFT may overflow using int arithmetic, + # so force use of double. */ + return func(x) + (e * float(SHIFT) * func(2.0)) +_loghelper._annspecialcase_ = 'specialize:arg0' + def _long_true_divide(a, b): try: ad, aexp = _AsScaledDouble(a) Modified: pypy/dist/pypy/rpython/module/test/test_ll_math.py ============================================================================== --- pypy/dist/pypy/rpython/module/test/test_ll_math.py (original) +++ pypy/dist/pypy/rpython/module/test/test_ll_math.py Wed Aug 24 18:26:08 2005 @@ -19,6 +19,8 @@ def test_ll_log(): assert ll_math_log(8943.790148912) == math.log(8943.790148912) assert ll_math_log10(8943.790148912) == math.log10(8943.790148912) + assert ll_math_log(1L << 10000) == math.log(1L << 10000) + assert ll_math_log10(1L << 10000) == math.log10(1L << 10000) def test_ll_cos_sin(): assert ll_math_cos(math.pi/3) == math.cos(math.pi/3) From jacob at codespeak.net Wed Aug 24 18:31:15 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Wed, 24 Aug 2005 18:31:15 +0200 (CEST) Subject: [pypy-svn] r16413 - in pypy/dist: lib-python/modified-2.4.1/test pypy/lib Message-ID: <20050824163115.C280627B5D@code1.codespeak.net> Author: jacob Date: Wed Aug 24 18:31:13 2005 New Revision: 16413 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_quopri.py pypy/dist/pypy/lib/binascii.py Log: Made binscii.py pass the test_quopri.py. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_quopri.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_quopri.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_quopri.py Wed Aug 24 18:31:13 2005 @@ -71,29 +71,42 @@ ('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\xd8\xd9\xda\xdb\xdc\xdd\xde\xdfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', '''xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=D8=D9=DA=DB=DC=DD=DE=DFx= xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'''), + # This is a silly test. The standard does not require you to not + # insert a soft line break. Inserting one requires look-ahead, + # which makes the code hideously complex and slow. + # In Pypy we remove it. + # A line of exactly 76 characters, no soft line break should be needed - ('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', - 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'), + # ('yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', + # 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'), + # A line of 77 characters, forcing a soft line break at position 75, # and a second line of exactly 2 characters (because the soft line # break `=' sign counts against the line length limit). ('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', '''zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz= zz'''), + # This is a silly test. The standard does not require you to not + # insert a soft line break. Inserting one requires look-ahead, + # which makes the code hideously complex and slow. + # In Pypy we remove it. + # A line of 151 characters, forcing a soft line break at position 75, # with a second line of exactly 76 characters and no trailing = - ('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', - '''zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz= -zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''), + #('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz', + #'''zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz=\nzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''), + + # This is a silly test. The standard does not require you to not + # insert a soft line break. Inserting one requires look-ahead, + # which makes the code hideously complex and slow. + # In Pypy we remove it. + # A string containing a hard line break, but which the first line is # 151 characters and the second line is exactly 76 characters. This # should leave us with three lines, the first which has a soft line # break, and which the second and third do not. - ('''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy -zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz''', - '''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy= -yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy -zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''), + #('''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\nzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz''', + #'''yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy=\nyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\nzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'''), # Now some really complex stuff ;) (DECSAMPLE, ENCSAMPLE), ) @@ -112,6 +125,8 @@ def test_encodestring(self): for p, e in self.STRINGS: + if encodestring(p) != e: + print '\n"%s" is different from \n"%s"' % (encodestring(p), e) self.assert_(encodestring(p) == e) def test_decodestring(self): Modified: pypy/dist/pypy/lib/binascii.py ============================================================================== --- pypy/dist/pypy/lib/binascii.py (original) +++ pypy/dist/pypy/lib/binascii.py Wed Aug 24 18:31:13 2005 @@ -225,13 +225,23 @@ table_b2a_base64[(b << 2) & 0x3F] + '=' return ''.join(result) + snippet + '\n' -def a2b_qp(s): - parts = s.rstrip().split('=') - +def a2b_qp(s, header=False): + parts = s.rstrip('\t ') + if header: + parts = ' '.join(parts.split('_')) + parts = parts.split('=') # Change the parts in-place for index, part in enumerate(parts[1:]): + if len(part) and part[0] == '\n': + parts[index + 1] = part[1:] + continue + if len(part) > 1 and part[0] == '\r' and part[1] == '\n': + parts[index + 1] = part[2:] + continue if len(part) > 1 and part[0] in hex_numbers and part[1] in hex_numbers: parts[index + 1] = chr(strhex_to_int(part[0:2])) + part[2:] + if parts[index + 1] == '_' and header: + parts[index + 1] = ' ' elif index == len(parts) - 2 and len(part) < 2: parts[index + 1] = '' else: @@ -239,17 +249,16 @@ return ''.join(parts) -def b2a_qp(s): - """ In this implementation, we are quoting all spaces and tab character. - This is ok by the standard, though it slightly reduces the - readability of the quoted string. The CPython implementation - preserves internal whitespace, which is a different way of - implementing the standard. The reason we are doing things differently - is that it greatly simplifies the code. - - The CPython implementation does not escape CR and LF characters - and does not encode newlines as CRLF sequences. This seems to be - non-standard, and we copy this behaviour. +def b2a_qp(s, quotetabs=False, istext=True, header=False): + """quotetabs=True means that tab and space characters are always + quoted. + istext=False means that \r and \n are treated as regular characters + header=True encodes space characters with '_' and requires + real '_' characters to be quoted. + + + The CPython does not encode newlines as CRLF sequences. This + seems to be non-standard, and we copy this behaviour. """ crlf = s.find('\r\n') lf = s.find('\n') @@ -269,24 +278,44 @@ lines = s.split('\n') + soft_lbr = '=\n' # The way CPython does it + #soft_lbr = '=\r\n' # The way I think the standard specifies result = [] for line in lines: charlist = [] count = 0 for c in line: - if '!' <= c <= '<' or '>' <= c <= '~' or c in '\n\r': + # Don't quote + if '!' <= c <= '<' or '>' <= c <= '^' or '`' <= c <= '~' or ( + c == '_' and not header) or (c in '\n\r' and istext): if count >= 75: - charlist.append('=\r\n') + charlist.append(soft_lbr) count = 0 charlist.append(c) count += 1 - else: + elif not quotetabs and c in '\t ': + if count >= 72: + charlist.append(soft_lbr) + count = 0 + + if count >= 71: # Quote + count += 3 + charlist.append('=' + two_hex_digits(ord(c))) + else: # Don't quote + if c == ' ' and header: + charlist.append('_') + else: + charlist.append(c) + count += 1 + else: # Quote if count >= 72: - charlist.append('=\r\n') + charlist.append(soft_lbr) count = 0 - snippet = '=' + two_hex_digits(ord(c)) - count += len(snippet) - charlist.append(snippet) + count += 3 + charlist.append('=' + two_hex_digits(ord(c))) + if charlist and charlist[-1] in '\t ': + # Whitespace at end of line has to be quoted + charlist[-1] = '=' + two_hex_digits(ord(charlist[-1])) result.append(''.join(charlist)) return linebreak.join(result) From nik at codespeak.net Wed Aug 24 18:33:15 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Wed, 24 Aug 2005 18:33:15 +0200 (CEST) Subject: [pypy-svn] r16414 - pypy/dist/pypy/module/_sre Message-ID: <20050824163315.23F8227B66@code1.codespeak.net> Author: nik Date: Wed Aug 24 18:33:14 2005 New Revision: 16414 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: discovered another RPython issue. the current interp_sre seems to compile now. Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Wed Aug 24 18:33:14 2005 @@ -159,21 +159,21 @@ def is_digit(space, w_char): code = space.int_w(space.ord(w_char)) - return code < 128 and ascii_char_info[code] & 1 + return code < 128 and (ascii_char_info[code] & 1 != 0) def is_uni_digit(space, w_char): return space.is_true(space.call_method(w_char, "isdigit")) def is_space(space, w_char): code = space.int_w(space.ord(w_char)) - return code < 128 and ascii_char_info[code] & 2 + return code < 128 and (ascii_char_info[code] & 2 != 0) def is_uni_space(space, w_char): return space.is_true(space.call_method(w_char, "isspace")) def is_word(space, w_char): code = space.int_w(space.ord(w_char)) - return code < 128 and ascii_char_info[code] & 16 + return code < 128 and (ascii_char_info[code] & 16 != 0) def is_uni_word(space, w_char): code = space.int_w(space.ord(w_char)) From ac at codespeak.net Wed Aug 24 18:39:30 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 18:39:30 +0200 (CEST) Subject: [pypy-svn] r16415 - pypy/dist/lib-python Message-ID: <20050824163930.4658827B66@code1.codespeak.net> Author: ac Date: Wed Aug 24 18:39:30 2005 New Revision: 16415 Modified: pypy/dist/lib-python/conftest.py Log: pickletools is not core. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 18:39:30 2005 @@ -362,7 +362,7 @@ RegrTest('test_anydbm.py', enabled=True), RegrTest('test_applesingle.py', enabled=False), RegrTest('test_array.py', enabled=True, core=True), - RegrTest('test_asynchat.py', enabled=False), + RegrTest('test_asynchat.py', enabled=False, usemodules='thread'), RegrTest('test_atexit.py', enabled=True, dumbtest=1, core=True), RegrTest('test_audioop.py', enabled=False, dumbtest=1), RegrTest('test_augassign.py', enabled=True, core=True), @@ -529,7 +529,7 @@ RegrTest('test_linuxaudiodev.py', enabled=False), RegrTest('test_list.py', enabled=True, core=True), RegrTest('test_locale.py', enabled=False, dumbtest=1), - RegrTest('test_logging.py', enabled=False), + RegrTest('test_logging.py', enabled=False, usemodules='thread'), RegrTest('test_long.py', enabled=True, dumbtest=1, core=True), RegrTest('test_long_future.py', enabled=True, dumbtest=1, core=True), RegrTest('test_longexp.py', enabled=True, core=True), @@ -579,7 +579,7 @@ # and is an unittest RegrTest('test_pep292.py', enabled=True), RegrTest('test_pickle.py', enabled=True, core=True), - RegrTest('test_pickletools.py', enabled=True, dumbtest=1, core=True), + RegrTest('test_pickletools.py', enabled=True, dumbtest=1, core=False), RegrTest('test_pkg.py', enabled=True, core=True), RegrTest('test_pkgimport.py', enabled=True, core=True), RegrTest('test_plistlib.py', enabled=False), @@ -637,12 +637,10 @@ RegrTest('test_site.py', enabled=False, core=False), # considered cpython impl-detail # Needs non-faked codecs. RegrTest('test_slice.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_socket.py', enabled=False), - #rev 10840: ImportError: thread + RegrTest('test_socket.py', enabled=False, usemodules='thread'), RegrTest('test_socket_ssl.py', enabled=False), - RegrTest('test_socketserver.py', enabled=False), - #rev 10840: ImportError: thread + RegrTest('test_socketserver.py', enabled=False, usemodules='thread'), RegrTest('test_softspace.py', enabled=True, dumbtest=1, core=True), RegrTest('test_sort.py', enabled=True, dumbtest=1, core=True), From hpk at codespeak.net Wed Aug 24 18:40:38 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 24 Aug 2005 18:40:38 +0200 (CEST) Subject: [pypy-svn] r16416 - in pypy/dist/pypy/interpreter: . stablecompiler test Message-ID: <20050824164038.AE37527B69@code1.codespeak.net> Author: hpk Date: Wed Aug 24 18:40:37 2005 New Revision: 16416 Modified: pypy/dist/pypy/interpreter/pyopcode.py pypy/dist/pypy/interpreter/stablecompiler/consts.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/symbols.py pypy/dist/pypy/interpreter/test/test_exec.py Log: (hpk, pedronis) fixing a couple of problems with the compiler package (XXX port to _stablecompiler) this is almost too involved to be described in detail right now. Basically we are trying to be more careful and specific regarding determining if we are in an optimized scope or not and also about forcing names in nested scopes to become globals. added new tests that now pass (and some in test_scope should be fixed by that) Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Wed Aug 24 18:40:37 2005 @@ -442,6 +442,8 @@ f.space.delitem(f.w_globals, w_varname) def LOAD_NAME(f, nameindex): + assert f.w_locals is not None, ( + "compiler probably wrongly assumes optimized scopes") if f.w_locals is not f.w_globals: w_varname = f.getname_w(nameindex) try: Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/consts.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/consts.py Wed Aug 24 18:40:37 2005 @@ -8,6 +8,7 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 +SC_DEFAULT = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Wed Aug 24 18:40:37 2005 @@ -9,7 +9,7 @@ from pypy.interpreter.stablecompiler import ast, parse, walk, syntax from pypy.interpreter.stablecompiler import pyassem, misc, future, symbols from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL + SC_FREE, SC_CELL, SC_DEFAULT from pypy.interpreter.stablecompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pypy.interpreter.stablecompiler.pyassem import TupleArg @@ -280,12 +280,14 @@ else: self.emit(prefix + '_FAST', name) elif scope == SC_GLOBAL: - if not self.optimized: - self.emit(prefix + '_NAME', name) - else: - self.emit(prefix + '_GLOBAL', name) + self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) + elif scope == SC_DEFAULT: + if self.optimized: + self.emit(prefix + '_GLOBAL', name) + else: + self.emit(prefix + '_NAME', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) @@ -1282,7 +1284,7 @@ args, hasTupleArg = generateArgList(func.argnames) self.graph = pyassem.PyFlowGraph(name, func.filename, args, - optimized=1) + self.optimized) self.isLambda = isLambda self.super_init() @@ -1338,6 +1340,7 @@ def __init__(self, func, scopes, isLambda, class_name, mod): self.scopes = scopes self.scope = scopes[func] + self.optimized = self.scope.optimized self.__super_init(func, scopes, isLambda, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py Wed Aug 24 18:40:37 2005 @@ -2,7 +2,7 @@ from pypy.interpreter.stablecompiler import ast from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL, SC_UNKNOWN + SC_FREE, SC_CELL, SC_UNKNOWN, SC_DEFAULT from pypy.interpreter.stablecompiler.misc import mangle import types @@ -12,6 +12,7 @@ MANGLE_LEN = 256 class Scope: + optimized = False # XXX how much information do I need about each name? def __init__(self, name, module, klass=None): self.name = name @@ -101,7 +102,7 @@ if self.nested: return SC_UNKNOWN else: - return SC_GLOBAL + return SC_DEFAULT def get_free_vars(self): if not self.nested: @@ -134,7 +135,8 @@ Be careful to stop if a child does not think the name is free. """ - self.globals[name] = 1 + if name not in self.defs: + self.globals[name] = 1 if self.frees.has_key(name): del self.frees[name] for child in self.children: @@ -178,6 +180,7 @@ self.__super_init("global", self) class FunctionScope(Scope): + optimized = True pass class GenExprScope(Scope): @@ -238,6 +241,12 @@ self.visit(node.code, scope) self.handle_free_vars(scope, parent) + def visitExec(self, node, parent): + # XXX check if we are a bare exec + parent.optimized = 0 + for child in node.getChildNodes(): + self.visit(child, parent) + def visitGenExpr(self, node, parent): scope = GenExprScope(self.module, self.klass); if parent.nested or isinstance(parent, FunctionScope) \ @@ -332,6 +341,7 @@ def visitFrom(self, node, scope): for name, asname in node.names: if name == "*": + scope.optimized = False continue scope.add_def(asname or name) Modified: pypy/dist/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exec.py (original) +++ pypy/dist/pypy/interpreter/test/test_exec.py Wed Aug 24 18:40:37 2005 @@ -78,6 +78,47 @@ def test_global_stmt(self): g = {} l = {} - exec "global a; a=5" in g, l + co = compile("global a; a=5", '', 'exec') + #import dis + #dis.dis(co) + exec co in g, l assert l == {} assert g['a'] == 5 + + def test_specialcase_free_load(self): + exec """if 1: + def f(): + exec 'a=3' + return a + x = f() + """ + assert x == 3 + + def test_specialcase_free_load2(self): + exec """if 1: + def f(): + a = 2 + exec 'a=3' + return a + x = f() + """ + assert x == 3 + + def test_nested_names_are_not_confused(self): + def get_nested_class(): + method_and_var = "var" + class Test: + def method_and_var(self): + return "method" + def test(self): + return method_and_var + def actual_global(self): + return str("global") + def str(self): + return str(self) + return Test() + t = get_nested_class() + assert t.actual_global() == "global" + assert t.test() == 'var' + assert t.method_and_var() == 'method' + From tismer at codespeak.net Wed Aug 24 18:42:26 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 24 Aug 2005 18:42:26 +0200 (CEST) Subject: [pypy-svn] r16417 - pypy/dist/pypy/lib/_stablecompiler Message-ID: <20050824164226.C5CED27B6D@code1.codespeak.net> Author: tismer Date: Wed Aug 24 18:42:25 2005 New Revision: 16417 Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py Log: small bug which costs time Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Wed Aug 24 18:42:25 2005 @@ -47,5 +47,6 @@ f = file('pythonname') res = f.read().strip() f.close() + return res except IOError: raise ValueError, "I need a local file 'pythonname'" From ac at codespeak.net Wed Aug 24 19:17:04 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 24 Aug 2005 19:17:04 +0200 (CEST) Subject: [pypy-svn] r16418 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20050824171704.4DECB27B3F@code1.codespeak.net> Author: ac Date: Wed Aug 24 19:17:03 2005 New Revision: 16418 Added: pypy/dist/lib-python/modified-2.4.1/pickletools.py - copied, changed from r16402, pypy/dist/lib-python/2.4.1/pickletools.py Log: Fix a doctest. From arigo at codespeak.net Wed Aug 24 19:17:48 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 19:17:48 +0200 (CEST) Subject: [pypy-svn] r16420 - pypy/dist/pypy/interpreter Message-ID: <20050824171748.3656E27B3F@code1.codespeak.net> Author: arigo Date: Wed Aug 24 19:17:45 2005 New Revision: 16420 Modified: pypy/dist/pypy/interpreter/function.py Log: Fix for test_class: * always delegate the __doc__ attribute from the method to the underlying function * should not call space.lookup() from the interpreter/ directory -- unless we review this policy at some later point(?). Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Wed Aug 24 19:17:45 2005 @@ -279,12 +279,15 @@ def descr_method_getattribute(self, w_attr): space = self.space - w_self = space.wrap(self) - w_result = space.lookup(w_self, space.str_w(w_attr)) - if w_result is None: - return space.getattr(self.w_function, w_attr) - else: - return space.get(w_result, w_self) + if space.str_w(w_attr) != '__doc__': + try: + return space.call_method(space.w_object, '__getattribute__', + space.wrap(self), w_attr) + except OperationError, e: + if not e.match(space, space.w_AttributeError): + raise + # fall-back to the attribute of the underlying 'im_func' + return space.getattr(self.w_function, w_attr) def descr_method_eq(self, w_other): space = self.space From jacob at codespeak.net Wed Aug 24 19:38:14 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Wed, 24 Aug 2005 19:38:14 +0200 (CEST) Subject: [pypy-svn] r16421 - pypy/dist/pypy/lib Message-ID: <20050824173814.8D8B327B3F@code1.codespeak.net> Author: jacob Date: Wed Aug 24 19:38:13 2005 New Revision: 16421 Modified: pypy/dist/pypy/lib/binascii.py Log: Slight cleanup. Modified: pypy/dist/pypy/lib/binascii.py ============================================================================== --- pypy/dist/pypy/lib/binascii.py (original) +++ pypy/dist/pypy/lib/binascii.py Wed Aug 24 19:38:13 2005 @@ -1,7 +1,7 @@ class Error(Exception): pass -class Apa(Exception): +class Done(Exception): pass class Incomplete(Exception): @@ -421,8 +421,7 @@ raise Error('Illegal character') elif res == DONE: yield t - print 'raising' - raise Apa + raise Done else: t.append(res) if len(t) == 4: @@ -443,7 +442,7 @@ result.append(chr(((snippet[1] & 0x0f) << 4) | (snippet[2] >> 2))) elif length == 2: result.append(chr(((snippet[0] & 0x3f) << 2) | (snippet[1] >> 4))) - except Apa: + except Done: done = 1 except Error: raise From cfbolz at codespeak.net Wed Aug 24 19:40:00 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 24 Aug 2005 19:40:00 +0200 (CEST) Subject: [pypy-svn] r16422 - in pypy/dist/pypy: interpreter module/errno module/errno/test Message-ID: <20050824174000.51AC727B3F@code1.codespeak.net> Author: cfbolz Date: Wed Aug 24 19:39:58 2005 New Revision: 16422 Added: pypy/dist/pypy/module/errno/ pypy/dist/pypy/module/errno/__init__.py pypy/dist/pypy/module/errno/interp_errno.py pypy/dist/pypy/module/errno/test/ pypy/dist/pypy/module/errno/test/test_errno.py Modified: pypy/dist/pypy/interpreter/baseobjspace.py Log: implemented errno module: very easy because it just contains constants that I steal from the underlying python implementation. not tested with translation :-( Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Aug 24 19:39:58 2005 @@ -164,12 +164,13 @@ pass modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', - 'array', 'marshal'] + 'array', 'marshal', 'errno'] if self.options.nofaking: modules.append('posix') modules.append('math') modules.append('time') + modules.append('errno') # there also are the '_sre' and 'marshal' modules # but those currently cause translation problems. You can Added: pypy/dist/pypy/module/errno/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/errno/__init__.py Wed Aug 24 19:39:58 2005 @@ -0,0 +1,26 @@ +# Package initialisation +from pypy.interpreter.mixedmodule import MixedModule +import errno + +class Module(MixedModule): + """This module makes available standard errno system symbols. + + The value of each symbol is the corresponding integer value, + e.g., on most systems, errno.ENOENT equals the integer 2. + + The dictionary errno.errorcode maps numeric codes to symbol names, + e.g., errno.errorcode[2] could be the string 'ENOENT'. + + Symbols that are not relevant to the underlying system are not defined. + + To map error codes to error messages, use the function os.strerror(), + e.g. os.strerror(2) could return 'No such file or directory'.""" + + appleveldefs = {} + interpleveldefs = {"errorcode": "interp_errno.get_errorcode(space)"} + +for name in dir(errno): + if name in ["__name__", "__doc__", "errorcode"]: + continue + Module.interpleveldefs[name] = ("space.wrap(%s)" % + (getattr(errno, name), )) Added: pypy/dist/pypy/module/errno/interp_errno.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/errno/interp_errno.py Wed Aug 24 19:39:58 2005 @@ -0,0 +1,5 @@ +import errno + +def get_errorcode(space): + return space.wrap(errno.errorcode) + Added: pypy/dist/pypy/module/errno/test/test_errno.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/errno/test/test_errno.py Wed Aug 24 19:39:58 2005 @@ -0,0 +1,21 @@ +from pypy.objspace.std import StdObjSpace +import py +import errno +def setup_module(mod): + mod.space = StdObjSpace(usemodules=['errno']) + +class AppTestErrno: + def setup_class(cls): + cls.space = space + cls.w_errno = space.appexec([], "(): import errno ; return errno") + cls.w_errorcode = space.wrap(errno.errorcode) + + def test_posix(self): + assert self.errno.__file__ + + def test_constants(self): + for code, name in self.errorcode.iteritems(): + assert getattr(self.errno, name) == code + + def test_errorcode(self): + assert self.errorcode == self.errno.errorcode From pedronis at codespeak.net Wed Aug 24 19:42:29 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 24 Aug 2005 19:42:29 +0200 (CEST) Subject: [pypy-svn] r16423 - pypy/dist/lib-python Message-ID: <20050824174229.C209427B3F@code1.codespeak.net> Author: pedronis Date: Wed Aug 24 19:42:27 2005 New Revision: 16423 Modified: pypy/dist/lib-python/conftest.py Log: this tests need the asian codecs, is not core Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 19:42:27 2005 @@ -547,7 +547,7 @@ RegrTest('test_minidom.py', enabled=False, dumbtest=1), RegrTest('test_mmap.py', enabled=False), RegrTest('test_module.py', enabled=True, dumbtest=1, core=True), - RegrTest('test_multibytecodec.py', enabled=True, core=True), + RegrTest('test_multibytecodec.py', enabled=True), RegrTest('test_multibytecodec_support.py', enabled=True, core=True), RegrTest('test_multifile.py', enabled=True), RegrTest('test_mutants.py', enabled=True, dumbtest=1, core="possibly"), From cfbolz at codespeak.net Wed Aug 24 19:42:48 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 24 Aug 2005 19:42:48 +0200 (CEST) Subject: [pypy-svn] r16424 - pypy/extradoc/sprintinfo Message-ID: <20050824174248.DC96827B3F@code1.codespeak.net> Author: cfbolz Date: Wed Aug 24 19:42:47 2005 New Revision: 16424 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: update: added errno Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Wed Aug 24 19:42:47 2005 @@ -104,7 +104,7 @@ Built-in modules:: - Do we still miss important os.* functionality? - - errno (easy for now) + - FIXED: errno (easy for now) - Enable our own array/_sre when translating (try with the current _sre and its interp-level parts, otherwise just use the app-level From hpk at codespeak.net Wed Aug 24 20:25:24 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 24 Aug 2005 20:25:24 +0200 (CEST) Subject: [pypy-svn] r16427 - in pypy/dist: lib-python pypy/tool/pytest Message-ID: <20050824182524.CC21227B48@code1.codespeak.net> Author: hpk Date: Wed Aug 24 20:25:24 2005 New Revision: 16427 Modified: pypy/dist/lib-python/conftest.py pypy/dist/pypy/tool/pytest/regrverbose.py Log: (hpk,nik) only run regression tests in verbose mode if we are not running an output tests (mirrors cpython regrtest.py behaviour) disabled test_zipimport.py because it depends on zlib which is a non-core module. improved the way tests are handled when invoking '-E' but there still seems to be something severly broken. tests with -E pass while they fail with a plain run. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 20:25:24 2005 @@ -260,6 +260,7 @@ space = self.space filename = str(self.fspath) callex(space, set_argv, space, space.wrap(filename)) + #space.call_function(self.w_method) callex(space, run_testcase_method, space, self.w_method) # ________________________________________________________________________ @@ -344,7 +345,13 @@ return prev ''') try: - callex(space, run_file, str(fspath), space) + modname = fspath.purebasename + space.appexec([], '''(): + from test import %(modname)s + m = %(modname)s + if hasattr(m, 'test_main'): + m.test_main() + ''' % locals()) finally: space.enable_new_style_classes_as_default_metaclass() if self.uselibfile: @@ -738,11 +745,12 @@ RegrTest('test_xpickle.py', enabled=False), RegrTest('test_xrange.py', enabled=True, core=True), RegrTest('test_zipfile.py', enabled=False, dumbtest=1), - RegrTest('test_zipimport.py', enabled=True, core=True), - #rev 10840: ImportError: zlib + RegrTest('test_zipimport.py', enabled=True), + # considered non-core because it depends on 'import zlib' + # which we don't have RegrTest('test_zlib.py', enabled=False), - #rev 10840: ImportError: zlib + #10840: ImportError: zlib ] class RegrDirectory(py.test.collect.Directory): @@ -858,10 +866,14 @@ # previously we only did it if regrtest.outputpath() was True # the regrverbose script now does the logic that CPython # uses in its regrtest.py - wrap = str(regr_script) + regrrun = str(regr_script) + regrrun_verbosity = regrtest.getoutputpath() and '1' or '0' + TIMEOUT = gettimeout() - cmd = "%s %s %d %s %s %s %s" %(python, alarm_script, TIMEOUT, - pypy_script, sopt, wrap, fspath.purebasename) + cmd = "%s %s %d %s %s %s %s %s" %( + python, alarm_script, TIMEOUT, + pypy_script, sopt, + regrrun, regrrun_verbosity, fspath.purebasename) return cmd def run(self): Modified: pypy/dist/pypy/tool/pytest/regrverbose.py ============================================================================== --- pypy/dist/pypy/tool/pytest/regrverbose.py (original) +++ pypy/dist/pypy/tool/pytest/regrverbose.py Wed Aug 24 20:25:24 2005 @@ -1,8 +1,8 @@ # refer to 2.4.1/test/regrtest.py's runtest() for comparison import sys from test import test_support -test_support.verbose = False -sys.argv[:] = sys.argv[1:] +test_support.verbose = int(sys.argv[1]) +sys.argv[:] = sys.argv[2:] modname = sys.argv[0] impname = 'test.' + modname From ludal at codespeak.net Wed Aug 24 20:41:47 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Wed, 24 Aug 2005 20:41:47 +0200 (CEST) Subject: [pypy-svn] r16428 - in pypy/dist/pypy: fakecompiler interpreter interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050824184147.243FE27B48@code1.codespeak.net> Author: ludal Date: Wed Aug 24 20:41:44 2005 New Revision: 16428 Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/lib/_stablecompiler/apphook.py pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Log: (ludal,arigo) + pass along the __future__ flags to the compiler(s) Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py ============================================================================== --- pypy/dist/pypy/fakecompiler/fakecompiler.py (original) +++ pypy/dist/pypy/fakecompiler/fakecompiler.py Wed Aug 24 20:41:44 2005 @@ -2,11 +2,12 @@ DUMPFILE = 'this_is_the_marshal_file' -def reallycompile(tuples, filename, mode): +def reallycompile(tuples, filename, mode, flag_names): + # XXX : use the flags if possible return parser.compileast(parser.tuple2ast(tuples), filename) if __name__ == '__main__': - tuples, filename, mode, done = marshal.load(file(DUMPFILE, "rb")) - code = reallycompile(tuples, filename, mode) + tuples, filename, mode, done, flag_names = marshal.load(file(DUMPFILE, "rb")) + code = reallycompile(tuples, filename, mode, flag_names) done = True - marshal.dump( (code, filename, mode, done), file(DUMPFILE, "wb"), 1) + marshal.dump( (code, filename, mode, done ), file(DUMPFILE, "wb"), 1) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Wed Aug 24 20:41:44 2005 @@ -87,6 +87,13 @@ compiler_flags |= flag compiler_features[fname] = flag +def get_flag_names( flag ): + flag_names = [] + for name, value in compiler_features.items(): + if flag & value: + flag_names.append( name ) + return flag_names + class CPythonCompiler(AbstractCompiler): """Faked implementation of a compiler, using the underlying compile().""" @@ -189,9 +196,9 @@ except ParseError, e: raise OperationError(space.w_SyntaxError, e.wrap_info(space, filename)) - return self.compile_parse_result(parse_result, filename, mode) + return self.compile_parse_result(parse_result, filename, mode, flags) - def compile_parse_result(self, parse_result, filename, mode): + def compile_parse_result(self, parse_result, filename, mode, flags): """NOT_RPYTHON""" from pyparser.pythonutil import parse_result_to_nested_tuples # the result of this conversion has no useful type in RPython @@ -209,12 +216,13 @@ transformer = Transformer() tree = transformer.compile_node(tuples) stablecompiler.misc.set_filename(filename, tree) + flag_names = get_flag_names( flags ) if mode == 'exec': - codegenerator = ModuleCodeGenerator(tree) + codegenerator = ModuleCodeGenerator(tree, flag_names) elif mode == 'single': - codegenerator = InteractiveCodeGenerator(tree) + codegenerator = InteractiveCodeGenerator(tree, flag_names) else: # mode == 'eval': - codegenerator = ExpressionCodeGenerator(tree) + codegenerator = ExpressionCodeGenerator(tree, flag_names) c = codegenerator.getCode() except SyntaxError, e: w_synerr = space.newtuple([space.wrap(e.msg), @@ -272,7 +280,7 @@ else: return self.w_compileapp - def compile_parse_result(self, parse_result, filename, mode): + def compile_parse_result(self, parse_result, filename, mode, flags): space = self.space if space.options.translating and not we_are_translated(): # to avoid to spend too much time in the app-level compiler @@ -280,8 +288,10 @@ # doesn't see this because it thinks that we_are_translated() # returns True. return PythonCompiler.compile_parse_result(self, parse_result, - filename, mode) + filename, mode, flags) source_encoding, stack_element = parse_result + flag_names = get_flag_names( flags ) + w_flag_names = space.newlist( [ space.wrap(n) for n in flag_names ] ) w_nested_tuples = stack_element.as_w_tuple(space, lineno=True) if source_encoding is not None: from pypy.interpreter.pyparser import pysymbol @@ -293,7 +303,8 @@ w_code = space.call_function(self._get_compiler(mode), w_nested_tuples, space.wrap(filename), - space.wrap(mode)) + space.wrap(mode), + w_flag_names) code = space.interpclass_w(w_code) from pypy.interpreter.pycode import PyCode if not isinstance(code, PyCode): @@ -321,9 +332,9 @@ except ParseError, e: raise OperationError(space.w_SyntaxError, e.wrap_info(space, filename)) - return self.compile_parse_result(ast_tree, filename, mode) + return self.compile_parse_result(ast_tree, filename, mode, flags) - def compile_parse_result(self, ast_tree, filename, mode): + def compile_parse_result(self, ast_tree, filename, mode, flags): """NOT_RPYTHON""" # __________ # XXX this uses the non-annotatable astcompiler at interp-level @@ -334,12 +345,13 @@ space = self.space try: astcompiler.misc.set_filename(filename, ast_tree) + flag_names = get_flag_names( flags ) if mode == 'exec': - codegenerator = ModuleCodeGenerator(ast_tree) + codegenerator = ModuleCodeGenerator(ast_tree, flag_names) elif mode == 'single': - codegenerator = InteractiveCodeGenerator(ast_tree) + codegenerator = InteractiveCodeGenerator(ast_tree, flag_names) else: # mode == 'eval': - codegenerator = ExpressionCodeGenerator(ast_tree) + codegenerator = ExpressionCodeGenerator(ast_tree, flag_names) c = codegenerator.getCode() except SyntaxError, e: w_synerr = space.newtuple([space.wrap(e.msg), @@ -355,22 +367,7 @@ raise OperationError(space.w_TypeError,space.wrap(str(e))) # __________ end of XXX above from pypy.interpreter.pycode import PyCode - code = PyCode(space) - code._code_new( c[0], - c[1], - c[2], - c[3], - c[4], - c[5], - c[6], - c[7], - c[8], - c[9], - c[10], - c[11], - c[12], - c[13], - ) + code = PyCode(space)._from_code(c) return code #compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Wed Aug 24 20:41:44 2005 @@ -1222,9 +1222,12 @@ scopes = None - def __init__(self, tree): + def __init__(self, tree, futures = []): self.graph = pyassem.PyFlowGraph("", tree.filename) self.futures = future.find_futures(tree) + for f in futures: + if f not in self.futures: + self.futures.append(f) self.__super_init() walk(tree, self) @@ -1235,10 +1238,10 @@ __super_init = CodeGenerator.__init__ scopes = None - futures = () - def __init__(self, tree): + def __init__(self, tree, futures=[]): self.graph = pyassem.PyFlowGraph("", tree.filename) + self.futures = futures[:] self.__super_init() walk(tree, self) @@ -1250,10 +1253,13 @@ __super_init = CodeGenerator.__init__ scopes = None - futures = () - def __init__(self, tree): + def __init__(self, tree, futures=[]): self.graph = pyassem.PyFlowGraph("", tree.filename) + self.futures = future.find_futures(tree) + for f in futures: + if f not in self.futures: + self.futures.append(f) self.__super_init() self.set_lineno(tree) walk(tree, self) Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Wed Aug 24 20:41:44 2005 @@ -9,16 +9,16 @@ from _stablecompiler.pycodegen import ExpressionCodeGenerator from _stablecompiler.transformer import Transformer -def applevelcompile(tuples, filename, mode): +def applevelcompile(tuples, filename, mode, flag_names ): transformer = Transformer() tree = transformer.compile_node(tuples) set_filename(filename, tree) if mode == 'exec': - codegenerator = ModuleCodeGenerator(tree) + codegenerator = ModuleCodeGenerator(tree, flag_names) elif mode == 'single': - codegenerator = InteractiveCodeGenerator(tree) + codegenerator = InteractiveCodeGenerator(tree, flag_names) else: # mode == 'eval': - codegenerator = ExpressionCodeGenerator(tree) + codegenerator = ExpressionCodeGenerator(tree, flag_names) return codegenerator.getCode() # temporary fake stuff, to allow to use the translated @@ -26,10 +26,10 @@ DUMPFILE = 'this_is_the_marshal_file' -def fakeapplevelcompile(tuples, filename, mode): +def fakeapplevelcompile(tuples, filename, mode, flag_names): import os, marshal done = False - data = marshal.dumps( (tuples, filename, mode, done) ) + data = marshal.dumps( (tuples, filename, mode, done, flag_names) ) f = file(DUMPFILE, "wb") f.write(data) f.close() Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Wed Aug 24 20:41:44 2005 @@ -1221,9 +1221,12 @@ scopes = None - def __init__(self, tree): + def __init__(self, tree, futures = []): self.graph = pyassem.PyFlowGraph("", tree.filename) self.futures = future.find_futures(tree) + for f in futures: + if f not in self.futures: + self.futures.append(f) self.__super_init() walk(tree, self) @@ -1234,10 +1237,10 @@ __super_init = CodeGenerator.__init__ scopes = None - futures = () - def __init__(self, tree): + def __init__(self, tree, futures=[]): self.graph = pyassem.PyFlowGraph("", tree.filename) + self.futures = futures[:] self.__super_init() walk(tree, self) @@ -1249,10 +1252,13 @@ __super_init = CodeGenerator.__init__ scopes = None - futures = () - def __init__(self, tree): + def __init__(self, tree, futures=[]): self.graph = pyassem.PyFlowGraph("", tree.filename) + self.futures = future.find_futures(tree) + for f in futures: + if f not in self.futures: + self.futures.append(f) self.__super_init() self.set_lineno(tree) walk(tree, self) From hpk at codespeak.net Wed Aug 24 21:08:27 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 24 Aug 2005 21:08:27 +0200 (CEST) Subject: [pypy-svn] r16429 - pypy/dist/pypy/tool/pytest Message-ID: <20050824190827.E243027B41@code1.codespeak.net> Author: hpk Date: Wed Aug 24 21:08:27 2005 New Revision: 16429 Modified: pypy/dist/pypy/tool/pytest/appsupport.py Log: only use frame when there is no AssertionError messages provided Modified: pypy/dist/pypy/tool/pytest/appsupport.py ============================================================================== --- pypy/dist/pypy/tool/pytest/appsupport.py (original) +++ pypy/dist/pypy/tool/pytest/appsupport.py Wed Aug 24 21:08:27 2005 @@ -97,7 +97,6 @@ space.wrap('__init__')) space.call_args(w_parent_init, __args__.prepend(w_self)) framestack = space.getexecutioncontext().framestack - frame = framestack.top(0) ## # Argh! we may see app-level helpers in the frame stack! ## # that's very probably very bad... ## if frame.code.co_name == 'normalize_exception': @@ -108,6 +107,7 @@ if args_w: w_msg = args_w[0] else: + frame = framestack.top(0) runner = AppFrame(frame) try: source = runner.statement From hpk at codespeak.net Wed Aug 24 21:10:51 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 24 Aug 2005 21:10:51 +0200 (CEST) Subject: [pypy-svn] r16430 - pypy/dist/lib-python Message-ID: <20050824191051.D528D27B41@code1.codespeak.net> Author: hpk Date: Wed Aug 24 21:10:51 2005 New Revision: 16430 Modified: pypy/dist/lib-python/conftest.py Log: (nik, hpk) finally hack py.test -E to at least not silently swallow errors from running testcase "methods" which really are testcase instances. We probably should run the test methods on our own (including setUp() and tearDown() because then we would have nicer tracebacks). Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Wed Aug 24 21:10:51 2005 @@ -131,7 +131,16 @@ return namemethodlist, doctestlist def run_testcase_method(method): - method() + result = method.defaultTestResult() + method.run(result) + if result.errors: + assert len(result.errors) + print result.errors[0][1] + if result.failures: + assert len(result.failures) + print result.failures[0][1] + if result.failures or result.errors: + return 1 def set_argv(filename): sys.argv[:] = ['python', filename] @@ -261,7 +270,10 @@ filename = str(self.fspath) callex(space, set_argv, space, space.wrap(filename)) #space.call_function(self.w_method) - callex(space, run_testcase_method, space, self.w_method) + res = callex(space, run_testcase_method, space, self.w_method) + if res: + raise AssertionError( + "testcase instance invociation raised errors, see stdoudt") # ________________________________________________________________________ # From tismer at codespeak.net Wed Aug 24 21:11:08 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 24 Aug 2005 21:11:08 +0200 (CEST) Subject: [pypy-svn] r16431 - pypy/dist/pypy/objspace/std Message-ID: <20050824191108.0491D27B41@code1.codespeak.net> Author: tismer Date: Wed Aug 24 21:11:07 2005 New Revision: 16431 Modified: pypy/dist/pypy/objspace/std/stdtypedef.py Log: support for extra_args was missing Modified: pypy/dist/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/dist/pypy/objspace/std/stdtypedef.py (original) +++ pypy/dist/pypy/objspace/std/stdtypedef.py Wed Aug 24 21:11:07 2005 @@ -186,8 +186,9 @@ raise Exception, "no longer supported, use __args__" if multimethod.extras.get('general__args__', False): wrapper_arglist.append('__args__') + wrapper_arglist += multimethod.extras.get('extra_args', ()) - miniglobals.update({ 'OperationError': OperationError, + miniglobals.update({ 'OperationError': OperationError, 'typeerrormsg': typeerrormsg}) app_defaults = multimethod.extras.get('defaults', ()) From tismer at codespeak.net Wed Aug 24 21:12:00 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 24 Aug 2005 21:12:00 +0200 (CEST) Subject: [pypy-svn] r16433 - in pypy/dist/pypy: module/math objspace/std Message-ID: <20050824191200.E202A27B41@code1.codespeak.net> Author: tismer Date: Wed Aug 24 21:11:59 2005 New Revision: 16433 Modified: pypy/dist/pypy/module/math/interp_math.py pypy/dist/pypy/objspace/std/floatobject.py pypy/dist/pypy/objspace/std/longobject.py pypy/dist/pypy/objspace/std/objspace.py Log: modified math.log to use a multimethod, because dispatching on an object's type is very messy if we don't use the space as *the* general interface. Modified: pypy/dist/pypy/module/math/interp_math.py ============================================================================== --- pypy/dist/pypy/module/math/interp_math.py (original) +++ pypy/dist/pypy/module/math/interp_math.py Wed Aug 24 21:11:59 2005 @@ -2,7 +2,6 @@ import math from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped -from pypy.objspace.std import longobject class State: def __init__(self, space): @@ -137,41 +136,15 @@ return space.wrap(x / degToRad) degrees.unwrap_spec = [ObjSpace, float] -def _log_float(space, x, base): - if base == 10.0: - return math1(space, math.log10, x) - num = math1_w(space, math.log, x) - if base == 0.0: - return space.wrap(num) - else: - den = math1_w(space, math.log, base) - return space.wrap(num / den) - def _log_any(space, w_x, base): try: - x = space.float_w(w_x) - except OperationError: - pass - else: - return _log_float(space, x, base) - try: - w_x = space.long(w_x) - except OperationError: - raise OperationError(space.w_TypeError, space.wrap( - 'a float is required')) # yes, this message is as bad as CPython's - try: - if base == 10.0: - return space.wrap(longobject._loghelper(math.log10, w_x)) - ret = longobject._loghelper(math.log, w_x) - if base != 0.0: - ret /= math.log(base) - return space.wrap(ret) + return space.log(w_x, base) except OverflowError: raise OperationError(space.w_OverflowError, - space.wrap("math range error")) + space.wrap('math range error')) except ValueError: raise OperationError(space.w_ValueError, - space.wrap("math domain error")) + space.wrap('math domain error')) def log(space, w_x, w_base=NoneNotWrapped): """log(x[, base]) -> the logarithm of x to the given base. @@ -180,11 +153,7 @@ if w_base is None: base = 0.0 else: - try: - base = space.float_w(w_base) - except OperationError: - raise OperationError(space.w_TypeError, space.wrap( - 'a float is required')) + base = space.float_w(w_base) if base <= 0.0: # just for raising the proper errors return math1(space, math.log, base) Modified: pypy/dist/pypy/objspace/std/floatobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/floatobject.py (original) +++ pypy/dist/pypy/objspace/std/floatobject.py Wed Aug 24 21:11:59 2005 @@ -413,6 +413,19 @@ def getnewargs__Float(space, w_float): return space.newtuple([W_FloatObject(space, w_float.floatval)]) +def log__Float(space, w_float, base): + # base is supposed to be positive or 0.0, which means we use e + x = space.float_w(w_float) + if base == 10.0: + return space.wrap(math.log10(x)) + num = math.log(x) + if base == 0.0: + return space.wrap(num) + else: + den = math.log(base) + return space.wrap(num / den) + + register_all(vars()) # pow delegation for negative 2nd arg Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Wed Aug 24 21:11:59 2005 @@ -565,6 +565,15 @@ def getnewargs__Long(space, w_long1): return space.newtuple([W_LongObject(space, w_long1.digits, w_long1.sign)]) +def log__Long(space, w_long, base): + # base is supposed to be positive or 0.0, which means we use e + if base == 10.0: + return space.wrap(_loghelper(math.log10, w_long)) + ret = _loghelper(math.log, w_long) + if base != 0.0: + ret /= math.log(base) + return space.wrap(ret) + register_all(vars()) @@ -605,6 +614,7 @@ 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) +#_________________________________________________________________ # Helper Functions def args_from_long(l): #YYYYYY Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Aug 24 21:11:59 2005 @@ -437,6 +437,7 @@ float_w = MultiMethod('float_w', 1, []) # returns an unwrapped float uint_w = MultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) marshal_w = MultiMethod('marshal_w', 1, [], extra_args=['marshaller']) + log = MultiMethod('log', 1, [], extra_args=['base']) # add all regular multimethods here for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: From arigo at codespeak.net Wed Aug 24 21:31:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 21:31:27 +0200 (CEST) Subject: [pypy-svn] r16434 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20050824193127.2368D27B41@code1.codespeak.net> Author: arigo Date: Wed Aug 24 21:31:26 2005 New Revision: 16434 Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py Log: (hpk, arigo) Don't de-optimize a function's locals in the presence of non-bare exec statements. Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py Wed Aug 24 21:31:26 2005 @@ -242,8 +242,8 @@ self.handle_free_vars(scope, parent) def visitExec(self, node, parent): - # XXX check if we are a bare exec - parent.optimized = 0 + if not (node.globals or node.locals): + parent.optimized = 0 # bare exec statement for child in node.getChildNodes(): self.visit(child, parent) From arigo at codespeak.net Wed Aug 24 21:43:57 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 24 Aug 2005 21:43:57 +0200 (CEST) Subject: [pypy-svn] r16435 - in pypy/dist/pypy: interpreter interpreter/stablecompiler interpreter/test objspace/std Message-ID: <20050824194357.AC39527B41@code1.codespeak.net> Author: arigo Date: Wed Aug 24 21:43:55 2005 New Revision: 16435 Modified: pypy/dist/pypy/interpreter/pyopcode.py pypy/dist/pypy/interpreter/stablecompiler/consts.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/symbols.py pypy/dist/pypy/interpreter/test/test_exec.py pypy/dist/pypy/objspace/std/typeobject.py Log: Temporarily moved away the scope changes of the "stablecompiler". Crashing example: def f(a): exec "" return a See CPython's dis.dis(f) to see what it does there... svn merge -r16434:16433 . svn merge -r16416:16415 . Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Wed Aug 24 21:43:55 2005 @@ -442,8 +442,6 @@ f.space.delitem(f.w_globals, w_varname) def LOAD_NAME(f, nameindex): - assert f.w_locals is not None, ( - "compiler probably wrongly assumes optimized scopes") if f.w_locals is not f.w_globals: w_varname = f.getname_w(nameindex) try: Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/consts.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/consts.py Wed Aug 24 21:43:55 2005 @@ -8,7 +8,6 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 -SC_DEFAULT = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Wed Aug 24 21:43:55 2005 @@ -9,7 +9,7 @@ from pypy.interpreter.stablecompiler import ast, parse, walk, syntax from pypy.interpreter.stablecompiler import pyassem, misc, future, symbols from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL, SC_DEFAULT + SC_FREE, SC_CELL from pypy.interpreter.stablecompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pypy.interpreter.stablecompiler.pyassem import TupleArg @@ -280,14 +280,12 @@ else: self.emit(prefix + '_FAST', name) elif scope == SC_GLOBAL: - self.emit(prefix + '_GLOBAL', name) + if not self.optimized: + self.emit(prefix + '_NAME', name) + else: + self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) - elif scope == SC_DEFAULT: - if self.optimized: - self.emit(prefix + '_GLOBAL', name) - else: - self.emit(prefix + '_NAME', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) @@ -1290,7 +1288,7 @@ args, hasTupleArg = generateArgList(func.argnames) self.graph = pyassem.PyFlowGraph(name, func.filename, args, - self.optimized) + optimized=1) self.isLambda = isLambda self.super_init() @@ -1346,7 +1344,6 @@ def __init__(self, func, scopes, isLambda, class_name, mod): self.scopes = scopes self.scope = scopes[func] - self.optimized = self.scope.optimized self.__super_init(func, scopes, isLambda, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py Wed Aug 24 21:43:55 2005 @@ -2,7 +2,7 @@ from pypy.interpreter.stablecompiler import ast from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL, SC_UNKNOWN, SC_DEFAULT + SC_FREE, SC_CELL, SC_UNKNOWN from pypy.interpreter.stablecompiler.misc import mangle import types @@ -12,7 +12,6 @@ MANGLE_LEN = 256 class Scope: - optimized = False # XXX how much information do I need about each name? def __init__(self, name, module, klass=None): self.name = name @@ -102,7 +101,7 @@ if self.nested: return SC_UNKNOWN else: - return SC_DEFAULT + return SC_GLOBAL def get_free_vars(self): if not self.nested: @@ -135,8 +134,7 @@ Be careful to stop if a child does not think the name is free. """ - if name not in self.defs: - self.globals[name] = 1 + self.globals[name] = 1 if self.frees.has_key(name): del self.frees[name] for child in self.children: @@ -180,7 +178,6 @@ self.__super_init("global", self) class FunctionScope(Scope): - optimized = True pass class GenExprScope(Scope): @@ -241,12 +238,6 @@ self.visit(node.code, scope) self.handle_free_vars(scope, parent) - def visitExec(self, node, parent): - if not (node.globals or node.locals): - parent.optimized = 0 # bare exec statement - for child in node.getChildNodes(): - self.visit(child, parent) - def visitGenExpr(self, node, parent): scope = GenExprScope(self.module, self.klass); if parent.nested or isinstance(parent, FunctionScope) \ @@ -341,7 +332,6 @@ def visitFrom(self, node, scope): for name, asname in node.names: if name == "*": - scope.optimized = False continue scope.add_def(asname or name) Modified: pypy/dist/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exec.py (original) +++ pypy/dist/pypy/interpreter/test/test_exec.py Wed Aug 24 21:43:55 2005 @@ -78,47 +78,6 @@ def test_global_stmt(self): g = {} l = {} - co = compile("global a; a=5", '', 'exec') - #import dis - #dis.dis(co) - exec co in g, l + exec "global a; a=5" in g, l assert l == {} assert g['a'] == 5 - - def test_specialcase_free_load(self): - exec """if 1: - def f(): - exec 'a=3' - return a - x = f() - """ - assert x == 3 - - def test_specialcase_free_load2(self): - exec """if 1: - def f(): - a = 2 - exec 'a=3' - return a - x = f() - """ - assert x == 3 - - def test_nested_names_are_not_confused(self): - def get_nested_class(): - method_and_var = "var" - class Test: - def method_and_var(self): - return "method" - def test(self): - return method_and_var - def actual_global(self): - return str("global") - def str(self): - return str(self) - return Test() - t = get_nested_class() - assert t.actual_global() == "global" - assert t.test() == 'var' - assert t.method_and_var() == 'method' - Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Wed Aug 24 21:43:55 2005 @@ -52,6 +52,10 @@ w_self.nslots = 0 w_self.w_bestbase = None + # make sure there is a __doc__ in dict_w + if '__doc__' not in dict_w: + dict_w['__doc__'] = space.w_None + if overridetypedef is not None: w_self.instancetypedef = overridetypedef w_self.hasdict = overridetypedef.hasdict From hpk at codespeak.net Wed Aug 24 22:28:32 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 24 Aug 2005 22:28:32 +0200 (CEST) Subject: [pypy-svn] r16437 - in pypy/dist/pypy/interpreter: stablecompiler test Message-ID: <20050824202832.41C8427B41@code1.codespeak.net> Author: hpk Date: Wed Aug 24 22:28:30 2005 New Revision: 16437 Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/symbols.py pypy/dist/pypy/interpreter/test/test_exec.py Log: (hpk,arigo) another go at getting the compiler related scoping problems under control. Added a couple of tests to show the desired behaviour. basically scopes keep track if locals are fully known or if an "from ... improt *" or bare "exec" basically introduces uncertainty. In the latter case "locallyfullyknown=False" the code generators will issue LOAD_NAME instead of LOAD_GLOBAL if they relate to such a scope. Modified: pypy/dist/pypy/interpreter/stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/consts.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/consts.py Wed Aug 24 22:28:30 2005 @@ -8,6 +8,7 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 +SC_DEFAULT = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Wed Aug 24 22:28:30 2005 @@ -9,7 +9,7 @@ from pypy.interpreter.stablecompiler import ast, parse, walk, syntax from pypy.interpreter.stablecompiler import pyassem, misc, future, symbols from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL + SC_FREE, SC_CELL, SC_DEFAULT from pypy.interpreter.stablecompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pypy.interpreter.stablecompiler.pyassem import TupleArg @@ -280,12 +280,14 @@ else: self.emit(prefix + '_FAST', name) elif scope == SC_GLOBAL: - if not self.optimized: - self.emit(prefix + '_NAME', name) - else: - self.emit(prefix + '_GLOBAL', name) + self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) + elif scope == SC_DEFAULT: + if self.optimized and self.localsfullyknown: + self.emit(prefix + '_GLOBAL', name) + else: + self.emit(prefix + '_NAME', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) @@ -1344,6 +1346,7 @@ def __init__(self, func, scopes, isLambda, class_name, mod): self.scopes = scopes self.scope = scopes[func] + self.localsfullyknown = self.scope.localsfullyknown self.__super_init(func, scopes, isLambda, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py Wed Aug 24 22:28:30 2005 @@ -2,7 +2,7 @@ from pypy.interpreter.stablecompiler import ast from pypy.interpreter.stablecompiler.consts import SC_LOCAL, SC_GLOBAL, \ - SC_FREE, SC_CELL, SC_UNKNOWN + SC_FREE, SC_CELL, SC_UNKNOWN, SC_DEFAULT from pypy.interpreter.stablecompiler.misc import mangle import types @@ -12,6 +12,7 @@ MANGLE_LEN = 256 class Scope: + localsfullyknown = True # XXX how much information do I need about each name? def __init__(self, name, module, klass=None): self.name = name @@ -101,7 +102,7 @@ if self.nested: return SC_UNKNOWN else: - return SC_GLOBAL + return SC_DEFAULT def get_free_vars(self): if not self.nested: @@ -134,7 +135,8 @@ Be careful to stop if a child does not think the name is free. """ - self.globals[name] = 1 + if name not in self.defs: + self.globals[name] = 1 if self.frees.has_key(name): del self.frees[name] for child in self.children: @@ -238,6 +240,12 @@ self.visit(node.code, scope) self.handle_free_vars(scope, parent) + def visitExec(self, node, parent): + if not (node.globals or node.locals): + parent.localsfullyknown = False # bare exec statement + for child in node.getChildNodes(): + self.visit(child, parent) + def visitGenExpr(self, node, parent): scope = GenExprScope(self.module, self.klass); if parent.nested or isinstance(parent, FunctionScope) \ @@ -332,6 +340,7 @@ def visitFrom(self, node, scope): for name, asname in node.names: if name == "*": + scope.localsfullyknown = False continue scope.add_def(asname or name) Modified: pypy/dist/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exec.py (original) +++ pypy/dist/pypy/interpreter/test/test_exec.py Wed Aug 24 22:28:30 2005 @@ -78,6 +78,84 @@ def test_global_stmt(self): g = {} l = {} - exec "global a; a=5" in g, l + co = compile("global a; a=5", '', 'exec') + #import dis + #dis.dis(co) + exec co in g, l assert l == {} assert g['a'] == 5 + + def test_specialcase_free_load(self): + exec """if 1: + def f(): + exec 'a=3' + return a + x = f() + """ + assert x == 3 + + def test_specialcase_free_load2(self): + exec """if 1: + def f(a): + exec 'a=3' + return a + x = f(4) + """ + assert x == 3 + + def test_specialcase_globals_and_exec(self): + d = {} + exec """if 1: + b = 2 + c = 3 + d = 4 + def f(a): + global b + exec 'd=42 ; b=7' + return a,b,c,d + #import dis + #dis.dis(f) + res = f(3) + """ in d + r = d['res'] + assert r == (3,2,3,42) + + def test_nested_names_are_not_confused(self): + def get_nested_class(): + method_and_var = "var" + class Test: + def method_and_var(self): + return "method" + def test(self): + return method_and_var + def actual_global(self): + return str("global") + def str(self): + return str(self) + return Test() + t = get_nested_class() + assert t.actual_global() == "global" + assert t.test() == 'var' + assert t.method_and_var() == 'method' + + def test_import_star_shadows_global(self): + d = {'platform' : 3} + exec """if 1: + def f(): + from sys import * + return platform + res = f()""" in d + import sys + assert d['res'] == sys.platform + + def test_import_global_takes_precendence(self): + d = {'platform' : 3} + exec """if 1: + def f(): + global platform + from sys import * + return platform + res = f()""" in d + import sys + assert d['platform'] == 3 + From tismer at codespeak.net Wed Aug 24 23:11:11 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 24 Aug 2005 23:11:11 +0200 (CEST) Subject: [pypy-svn] r16438 - pypy/dist/pypy/translator/c/src Message-ID: <20050824211111.E4E6227B41@code1.codespeak.net> Author: tismer Date: Wed Aug 24 23:11:09 2005 New Revision: 16438 Modified: pypy/dist/pypy/translator/c/src/g_prerequisite.h pypy/dist/pypy/translator/c/src/thread_nt.h Log: a few changes to make things compile on Windooze, again Modified: pypy/dist/pypy/translator/c/src/g_prerequisite.h ============================================================================== --- pypy/dist/pypy/translator/c/src/g_prerequisite.h (original) +++ pypy/dist/pypy/translator/c/src/g_prerequisite.h Wed Aug 24 23:11:09 2005 @@ -6,7 +6,9 @@ * executables (which are *not* linked against CPython then), * to get the convenient macro definitions */ +#ifdef PYPY_STANDALONE #define Py_BUILD_CORE /* for Windows: avoid pulling libs in */ +#endif #include "Python.h" Modified: pypy/dist/pypy/translator/c/src/thread_nt.h ============================================================================== --- pypy/dist/pypy/translator/c/src/thread_nt.h (original) +++ pypy/dist/pypy/translator/c/src/thread_nt.h Wed Aug 24 23:11:09 2005 @@ -17,7 +17,7 @@ * Return the thread Id instead of an handle. The Id is said to uniquely identify the thread in the system */ -#define PyThreadGetIdent GetCurrentThreadId +#define RPyThreadGetIdent GetCurrentThreadId typedef struct { void (*func)(void*); @@ -34,13 +34,13 @@ void (*func)(void*) = obj->func; void *arg = obj->arg; - obj->id = PyThreadGetIdent(); + obj->id = RPyThreadGetIdent(); ReleaseSemaphore(obj->done, 1, NULL); func(arg); return 0; } -long PyThreadStart(void (*func)(void *), void *arg) +long RPyThreadStart(void (*func)(void *), void *arg) { unsigned long rv; callobj obj; From tismer at codespeak.net Thu Aug 25 00:08:10 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 25 Aug 2005 00:08:10 +0200 (CEST) Subject: [pypy-svn] r16439 - in pypy/dist/pypy: module/posix rpython rpython/module translator/c translator/c/src translator/c/test Message-ID: <20050824220810.826A127B41@code1.codespeak.net> Author: tismer Date: Thu Aug 25 00:08:05 2005 New Revision: 16439 Modified: pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/module/posix/interp_posix.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: added os.remove and os.unlink. This was missing in order to run tests with the compiled pypy. Also started to add the proper docstrings. I'm not sure whether we should do this or fetch them from the according CPython functions? A remaining blocker that still hinders me from testing is that the compiler seems to crash the compiled PyPy. Try for instance the file test_complex. If you put the whole big class into a triple quoted string ('''), it at least tries to do something. Otherwise, the session immediately crashes, whether interactive or not! Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Thu Aug 25 00:08:05 2005 @@ -25,6 +25,8 @@ 'stat' : 'interp_posix.stat', 'dup' : 'interp_posix.dup', 'system' : 'interp_posix.system', + 'unlink' : 'interp_posix.unlink', + 'remove' : 'interp_posix.remove', } if hasattr(os, 'ftruncate'): interpleveldefs['ftruncate'] = 'interp_posix.ftruncate' Modified: pypy/dist/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/dist/pypy/module/posix/interp_posix.py (original) +++ pypy/dist/pypy/module/posix/interp_posix.py Thu Aug 25 00:08:05 2005 @@ -118,6 +118,9 @@ dup.unwrap_spec = [ObjSpace, int] def system(space, cmd): + """system(command) -> exit_status + +Execute the command (a string) in a subshell.""" try: rc = os.system(cmd) except OSError, e: @@ -125,3 +128,23 @@ else: return space.wrap(rc) system.unwrap_spec = [ObjSpace, str] + +def unlink(space, path): + """unlink(path) + +Remove a file (same as remove(path)).""" + try: + os.unlink(path) + except OSError, e: + raise wrap_oserror(space, e) +unlink.unwrap_spec = [ObjSpace, str] + +def remove(space, path): + """remove(path) + +Remove a file (same as unlink(path)).""" + try: + os.unlink(path) + except OSError, e: + raise wrap_oserror(space, e) +remove.unwrap_spec = [ObjSpace, str] Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Thu Aug 25 00:08:05 2005 @@ -142,7 +142,8 @@ declare(os.fstat , statannotation, 'll_os/fstat') declare(os.stat , statannotation, 'll_os/stat') declare(os.system , int , 'll_os/system') -declare(os.strerror , str , 'll_os/strerror') +declare(os.unlink , noneannotation, 'll_os/unlink') +declare(os.strerror , str , 'll_os/strerror') declare(os.path.exists, bool , 'll_os_path/exists') declare(os.path.isdir, bool , 'll_os_path/isdir') declare(time.time , float , 'll_time/time') Modified: pypy/dist/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/module/ll_os.py Thu Aug 25 00:08:05 2005 @@ -117,3 +117,7 @@ def ll_os_system(cmd): return os.system(from_rstr(cmd)) ll_os_system.suggested_primitive = True + +def ll_os_unlink(path): + os.unlink(from_rstr(path)) +ll_os_unlink.suggested_primitive = True Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Thu Aug 25 00:08:05 2005 @@ -23,6 +23,7 @@ ll_os .ll_os_ftruncate:'LL_os_ftruncate', ll_os .ll_os_strerror: 'LL_os_strerror', ll_os .ll_os_system: 'LL_os_system', + ll_os .ll_os_unlink: 'LL_os_unlink', ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', ll_time.ll_time_time: 'LL_time_time', Modified: pypy/dist/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_os.h (original) +++ pypy/dist/pypy/translator/c/src/ll_os.h Thu Aug 25 00:08:05 2005 @@ -183,3 +183,10 @@ long LL_os_system(RPyString * fname) { return system(RPyString_AsString(fname)); } + +void LL_os_unlink(RPyString * fname) { + int error = unlink(RPyString_AsString(fname)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Thu Aug 25 00:08:05 2005 @@ -239,7 +239,7 @@ 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(): @@ -389,3 +389,12 @@ assert res is True res = f(1) assert res is False + +def test_os_unlink(): + tmpfile = str(udir.join('test_os_path_exists.TMP')) + def fn(): + os.unlink(tmpfile) + f = compile(fn, []) + open(tmpfile, 'w').close() + fn() + assert not os.path.exists(tmpfile) From ludal at codespeak.net Thu Aug 25 10:52:04 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 10:52:04 +0200 (CEST) Subject: [pypy-svn] r16442 - pypy/dist/pypy/interpreter Message-ID: <20050825085204.C7FD427B48@code1.codespeak.net> Author: ludal Date: Thu Aug 25 10:52:02 2005 New Revision: 16442 Modified: pypy/dist/pypy/interpreter/pycode.py Log: added a method to create pycode objects from astcompiler - more precisely it takes consts tuples of already wrapped objects (including PyCode objects) Modified: pypy/dist/pypy/interpreter/pycode.py ============================================================================== --- pypy/dist/pypy/interpreter/pycode.py (original) +++ pypy/dist/pypy/interpreter/pycode.py Thu Aug 25 10:52:02 2005 @@ -142,7 +142,7 @@ space = self.space newconsts_w = [] for const in consts: - if isinstance(const, types.CodeType): + if isinstance(const, types.CodeType): # from stable compiler const = PyCode(space)._from_code(const, hidden_applevel=hidden_applevel) newconsts_w.append(space.wrap(const)) self.co_consts_w = newconsts_w @@ -174,6 +174,52 @@ hidden_applevel ) return self + + + def _code_new_w( self, argcount, nlocals, stacksize, flags, + code, consts, names, varnames, filename, + name, firstlineno, lnotab, freevars, cellvars, + hidden_applevel=False): + """Initialize a new code objects from parameters given by + the pypy compiler""" + # simply try to suck in all attributes we know of + # with a lot of boring asserts to enforce type knowledge + # XXX get rid of that ASAP with a real compiler! + import types + x = argcount; assert isinstance(x, int) + self.co_argcount = x + x = nlocals; assert isinstance(x, int) + self.co_nlocals = x + x = stacksize; assert isinstance(x, int) + self.co_stacksize = x + x = flags; assert isinstance(x, int) + self.co_flags = x + x = code; assert isinstance(x, str) + self.co_code = x +## for w in consts: +## assert isinstance(w,W_Root) + self.co_consts_w = consts + x = names; assert isinstance(x, tuple) + self.co_names = [ str(n) for n in x ] + x = varnames; assert isinstance(x, tuple) + self.co_varnames = [ str(n) for n in x ] + x = freevars; assert isinstance(x, tuple) + self.co_freevars = [ str(n) for n in x ] + x = cellvars; assert isinstance(x, tuple) + self.co_cellvars = [ str(n) for n in x ] + x = filename; assert isinstance(x, str) + self.co_filename = x + x = name; assert isinstance(x, str) + self.co_name = x + x = firstlineno; assert isinstance(x, int) + self.co_firstlineno = x + x = lnotab; assert isinstance(x, str) + self.co_lnotab = x + # recursively _from_code()-ify the code objects in code.co_consts + space = self.space + return self + + def create_frame(self, space, w_globals, closure=None): "Create an empty PyFrame suitable for this code object." # select the appropriate kind of frame From ale at codespeak.net Thu Aug 25 11:03:50 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 11:03:50 +0200 (CEST) Subject: [pypy-svn] r16443 - pypy/dist/pypy/objspace/std Message-ID: <20050825090350.4B4C927B48@code1.codespeak.net> Author: ale Date: Thu Aug 25 11:03:48 2005 New Revision: 16443 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py Log: (arre, ale) Added support for UTF-16 surrogate pairs in repr. Prepared move of unicode repr code to _codecs unicodeescape_string. THe move is not performed until after 0.7 Modified: pypy/dist/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodeobject.py (original) +++ pypy/dist/pypy/objspace/std/unicodeobject.py Thu Aug 25 11:03:48 2005 @@ -880,13 +880,17 @@ type(retval).__name__) return retval +def repr__Unicode(unistr): + import _codecs + return ''.join(_codecs.unicodeescape_string(unistr,len(unistr),True)) + ''') unicode_expandtabs__Unicode_ANY = app.interphook('unicode_expandtabs__Unicode_ANY') unicode_translate__Unicode_ANY = app.interphook('unicode_translate__Unicode_ANY') mod__Unicode_ANY = app.interphook('mod__Unicode_ANY') - unicode_encode__Unicode_ANY_ANY = app.interphook('unicode_encode__Unicode_ANY_ANY') +# Move this into the _codecs module as 'unicodeescape_string (Remember to cater for quotes)' def repr__Unicode(space, w_unicode): hexdigits = "0123456789abcdef" chars = w_unicode._value @@ -906,7 +910,9 @@ result[0] = 'u' result[1] = quote i = 2 - for ch in chars: + j = 0 + while j> 4) & 0xf] result[i + 9] = hexdigits[(code >> 0) & 0xf] i += 10 + j += 1 continue + if code >= 0xD800 and code < 0xDC00: + ch2 = chars[j+1] + code2 = ord(ch2) + if code2 >= 0xDC00 and code2 <= 0xDFFF: + code = (((code & 0x03FF) << 10) | (code2 & 0x03FF)) + 0x00010000 + if i + 12 > len(result): + result.extend(['\0'] * 100) + result[i] = '\\' + result[i + 1] = "U" + result[i + 2] = hexdigits[(code >> 28) & 0xf] + result[i + 3] = hexdigits[(code >> 24) & 0xf] + result[i + 4] = hexdigits[(code >> 20) & 0xf] + result[i + 5] = hexdigits[(code >> 16) & 0xf] + result[i + 6] = hexdigits[(code >> 12) & 0xf] + result[i + 7] = hexdigits[(code >> 8) & 0xf] + result[i + 8] = hexdigits[(code >> 4) & 0xf] + result[i + 9] = hexdigits[(code >> 0) & 0xf] + i += 10 + j += 2 + continue + if code >= 0x100: result[i] = '\\' result[i + 1] = "u" @@ -939,26 +967,31 @@ result[i + 4] = hexdigits[(code >> 4) & 0xf] result[i + 5] = hexdigits[(code >> 0) & 0xf] i += 6 + j += 1 continue if code == ord('\\') or code == ord(quote): result[i] = '\\' result[i + 1] = chr(code) i += 2 + j += 1 continue if code == ord('\t'): result[i] = '\\' result[i + 1] = "t" i += 2 + j += 1 continue if code == ord('\r'): result[i] = '\\' result[i + 1] = "r" i += 2 + j += 1 continue if code == ord('\n'): result[i] = '\\' result[i + 1] = "n" i += 2 + j += 1 continue if code < ord(' ') or code >= 0x7f: result[i] = '\\' @@ -966,13 +999,16 @@ result[i + 2] = hexdigits[(code >> 4) & 0xf] result[i + 3] = hexdigits[(code >> 0) & 0xf] i += 4 + j += 1 continue result[i] = chr(code) i += 1 + j += 1 result[i] = quote i += 1 return space.wrap(''.join(result[:i])) +#repr__Unicode = app.interphook('repr__Unicode') # uncomment when repr code is moved to _codecs import unicodetype register_all(vars(), unicodetype) From ludal at codespeak.net Thu Aug 25 11:04:17 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 11:04:17 +0200 (CEST) Subject: [pypy-svn] r16444 - pypy/dist/pypy/objspace/std/test Message-ID: <20050825090417.944B027B4E@code1.codespeak.net> Author: ludal Date: Thu Aug 25 11:04:15 2005 New Revision: 16444 Modified: pypy/dist/pypy/objspace/std/test/test_typeobject.py Log: - we now have the __doc__ attribute in the class __dict__ so change the test Modified: pypy/dist/pypy/objspace/std/test/test_typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_typeobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_typeobject.py Thu Aug 25 11:04:15 2005 @@ -321,7 +321,7 @@ class C: __metaclass__ = T assert d - assert sorted(d[0].keys()) == ['__dict__','__metaclass__','__module__'] + assert sorted(d[0].keys()) == ['__dict__','__doc__','__metaclass__','__module__'] d = [] class T(type): def mro(cls): From ericvrp at codespeak.net Thu Aug 25 11:06:23 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 11:06:23 +0200 (CEST) Subject: [pypy-svn] r16445 - pypy/dist/pypy/translator/goal Message-ID: <20050825090623.977A627B54@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 11:06:22 2005 New Revision: 16445 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: Added -fork2 option that forks just before backend code generation Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Thu Aug 25 11:06:22 2005 @@ -18,6 +18,7 @@ -no-o Don't do backend-oriented optimizations -no-c Don't generate the C code -fork (UNIX) Create a restartable checkpoint after annotation + -fork2 (UNIX) Create a restartable checkpoint after specializing -llvm Use LLVM instead of C -c Generate the C code, but don't compile it -boehm Use the Boehm collector when generating C code @@ -143,6 +144,9 @@ if not options['-no-o'] and not options['-llvm']: print 'Back-end optimizations...' t.backend_optimizations() + if a and options['-fork2']: + from pypy.translator.goal import unixcheckpoint + unixcheckpoint.restartable_point(auto='run') if a: t.frozen = True # cannot freeze if we don't have annotations @@ -346,6 +350,7 @@ '-load': False, '-save': False, '-fork': False, + '-fork2': False, '-llinterpret': False, '-batch': False, } From ludal at codespeak.net Thu Aug 25 11:06:34 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 11:06:34 +0200 (CEST) Subject: [pypy-svn] r16446 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050825090634.1316D27B56@code1.codespeak.net> Author: ludal Date: Thu Aug 25 11:06:33 2005 New Revision: 16446 Modified: pypy/dist/pypy/interpreter/pyparser/error.py Log: added SyntaxError class because we raise it and it needs to be annotatable Modified: pypy/dist/pypy/interpreter/pyparser/error.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/error.py (original) +++ pypy/dist/pypy/interpreter/pyparser/error.py Thu Aug 25 11:06:33 2005 @@ -22,3 +22,28 @@ self.lineno, self.offset, self.text) + + +class SyntaxError(Exception): + """Base class for exceptions raised by the parser.""" + + def __init__(self, msg, lineno=0, offset=0, text=0): + self.msg = msg + self.lineno = lineno + self.offset = offset + self.text = text + self.filename = "" + self.print_file_and_line = False + + def wrap_info(self, space, filename): + return space.newtuple([space.wrap(self.msg), + space.newtuple([space.wrap(filename), + space.wrap(self.lineno), + space.wrap(self.offset), + space.wrap(self.text)])]) + + def __str__(self): + return "%s at pos (%d, %d) in %r" % (self.__class__.__name__, + self.lineno, + self.offset, + self.text) From ale at codespeak.net Thu Aug 25 11:07:05 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 11:07:05 +0200 (CEST) Subject: [pypy-svn] r16447 - pypy/dist/pypy/module/_codecs Message-ID: <20050825090705.C2D6927B58@code1.codespeak.net> Author: ale Date: Thu Aug 25 11:07:04 2005 New Revision: 16447 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: (arre, ale) found a bug in unicodeescape_string. This code is scheduled for replacement with the code in repr_Unicode in objspace/std/unicodobject.py Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Thu Aug 25 11:07:04 2005 @@ -789,7 +789,7 @@ #/* Escape quotes */ if (quotes and (ch == p[1] or ch == '\\')): p += '\\' - p += ch + p += chr(ord(ch)) pos += 1 continue From rxe at codespeak.net Thu Aug 25 11:21:17 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 11:21:17 +0200 (CEST) Subject: [pypy-svn] r16448 - in pypy/dist/pypy/translator/llvm2: module test Message-ID: <20050825092117.4938927B64@code1.codespeak.net> Author: rxe Date: Thu Aug 25 11:21:15 2005 New Revision: 16448 Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: Generated code to make test_math_frexp work. Added helpers prepare_and_raise_xxx llvm functions to be called from c code (once compiled to llvm). Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Thu Aug 25 11:21:15 2005 @@ -47,12 +47,12 @@ for function in functions: extfunctions["%ll_math_" + function] = ((), simple_function_template % locals()) -extfunctions["%ll_math_frexp"] = (("%__debug",), """ -internal fastcc %RPyFREXP_RESULT* %ll_math_frexp(double %x) { - call fastcc void %__debug([12 x sbyte]* %__ll_math_frexp) ; XXX: TODO: ll_math_frexp - ret %RPyFREXP_RESULT* null -} -""") +#extfunctions["%ll_math_frexp"] = (("%__debug",), """ +#internal fastcc %RPyFREXP_RESULT* %ll_math_frexp(double %x) { +# call fastcc void %__debug([12 x sbyte]* %__ll_math_frexp) ; XXX: TODO: ll_math_frexp +# ret %RPyFREXP_RESULT* null +#} +#""") extfunctions["%ll_math_hypot"] = (("%__debug",), """ internal fastcc double %ll_math_hypot(double %x, double %y) { @@ -81,3 +81,122 @@ ret double 0.0 } """) +#;;;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + + +extfunctions["%ll_math_frexp"] = (("%prepare_and_raise_OverflowError", + "%prepare_and_raise_ValueError"), """ +declare int* %__errno_location() + +internal fastcc int %ll_math_is_error(double %x) { +entry: + %x_addr = alloca double ; ty=double* + %result = alloca int ; ty=int* + store double %x, double* %x_addr + %tmp.0 = call int* ()* %__errno_location() ; ty=int* + %tmp.1 = load int* %tmp.0 ; ty=int + %tmp.2 = seteq int %tmp.1, 34 ; ty=bool + %tmp.3 = cast bool %tmp.2 to int ; ty=int + br bool %tmp.2, label %then.0, label %else +then.0: + %tmp.4 = load double* %x_addr ; ty=double + %tmp.5 = seteq double %tmp.4, 0x0000000000000000 ; ty=bool + %tmp.6 = cast bool %tmp.5 to int ; ty=int + br bool %tmp.5, label %then.1, label %endif.1 +then.1: + store int 0, int* %result + br label %return +after_ret.0: + br label %endif.1 +endif.1: + call fastcc void (sbyte*)* %prepare_and_raise_OverflowError(sbyte* getelementptr ([17 x sbyte]* %.str_1, int 0, int 0)) + br label %endif.0 +else: + call fastcc void (sbyte*)* %prepare_and_raise_ValueError(sbyte* getelementptr ([18 x sbyte]* %.str_2, int 0, int 0)) + br label %endif.0 +endif.0: + store int 1, int* %result + br label %return +after_ret.1: + br label %return +return: + %tmp.9 = load int* %result ; ty=int + ret int %tmp.9 +} + +internal fastcc %RPyFREXP_RESULT* %ll_math_frexp(double %x) { +entry: + %x_addr = alloca double ; ty=double* + %result = alloca %RPyFREXP_RESULT* ; ty=%RPyFREXP_RESULT** + %expo = alloca int ; ty=int* + %m = alloca double ; ty=double* + store double %x, double* %x_addr + %tmp.0 = call int* ()* %__errno_location() ; ty=int* + store int 0, int* %tmp.0 + %tmp.2 = load double* %x_addr ; ty=double + %tmp.1 = call double (double, int*)* %frexp(double %tmp.2, int* %expo) ; ty=double + store double %tmp.1, double* %m + %tmp.3 = call int* ()* %__errno_location() ; ty=int* + %tmp.4 = load int* %tmp.3 ; ty=int + %tmp.5 = seteq int %tmp.4, 0 ; ty=bool + %tmp.6 = cast bool %tmp.5 to int ; ty=int + br bool %tmp.5, label %shortcirc_next.0, label %shortcirc_done.0 +shortcirc_next.0: + %tmp.7 = load double* %m ; ty=double + %tmp.8 = setgt double %tmp.7, 0x7FEFFFFFFFFFFFFF ; ty=bool + %tmp.9 = cast bool %tmp.8 to int ; ty=int + br bool %tmp.8, label %shortcirc_done.1, label %shortcirc_next.1 +shortcirc_next.1: + %tmp.10 = load double* %m ; ty=double + %tmp.11 = setlt double %tmp.10, 0xFFEFFFFFFFFFFFFF ; ty=bool + %tmp.12 = cast bool %tmp.11 to int ; ty=int + br label %shortcirc_done.1 +shortcirc_done.1: + %shortcirc_val.0 = phi bool [ true, %shortcirc_next.0 ], [ %tmp.11, %shortcirc_next.1 ] ; ty=bool + %tmp.13 = cast bool %shortcirc_val.0 to int ; ty=int + br label %shortcirc_done.0 +shortcirc_done.0: + %shortcirc_val.1 = phi bool [ false, %entry ], [ %shortcirc_val.0, %shortcirc_done.1 ] ; ty=bool + %tmp.14 = cast bool %shortcirc_val.1 to int ; ty=int + br bool %shortcirc_val.1, label %then.0, label %endif.0 +then.0: + %tmp.15 = call int* ()* %__errno_location() ; ty=int* + store int 34, int* %tmp.15 + br label %endif.0 +endif.0: + %tmp.16 = call int* ()* %__errno_location() ; ty=int* + %tmp.17 = load int* %tmp.16 ; ty=int + %tmp.18 = setne int %tmp.17, 0 ; ty=bool + %tmp.19 = cast bool %tmp.18 to int ; ty=int + br bool %tmp.18, label %shortcirc_next.2, label %shortcirc_done.2 +shortcirc_next.2: + %tmp.21 = load double* %m ; ty=double + %tmp.20 = call fastcc int (double)* %ll_math_is_error(double %tmp.21) ; ty=int + %tmp.22 = setne int %tmp.20, 0 ; ty=bool + %tmp.23 = cast bool %tmp.22 to int ; ty=int + br label %shortcirc_done.2 +shortcirc_done.2: + %shortcirc_val.2 = phi bool [ false, %endif.0 ], [ %tmp.22, %shortcirc_next.2 ] ; ty=bool + %tmp.24 = cast bool %shortcirc_val.2 to int ; ty=int + br bool %shortcirc_val.2, label %then.1, label %endif.1 +then.1: + store %RPyFREXP_RESULT* null, %RPyFREXP_RESULT** %result + br label %return +after_ret.0: + br label %endif.1 +endif.1: + %tmp.26 = load double* %m ; ty=double + %tmp.27 = load int* %expo ; ty=int + %tmp.25 = call fastcc %RPyFREXP_RESULT* (double, int)* %ll_frexp_result__Float_Signed(double %tmp.26, int %tmp.27) ; ty=%RPyFREXP_RESULT* + store %RPyFREXP_RESULT* %tmp.25, %RPyFREXP_RESULT** %result + br label %return +after_ret.1: + br label %return +return: + %tmp.28 = load %RPyFREXP_RESULT** %result ; ty=%RPyFREXP_RESULT* + ret %RPyFREXP_RESULT* %tmp.28 +} + +""") + + Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 11:21:15 2005 @@ -5,9 +5,12 @@ declare ccc INT %strlen(sbyte*) declare ccc INT %strcmp(sbyte*, sbyte*) declare ccc sbyte* %memset(sbyte*, INT, UINT) +declare ccc double %frexp(double, int*) %__print_debug_info = internal global bool false %__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" +%.str_1 = internal constant [17 x sbyte] c"math range error\\00" +%.str_2 = internal constant [18 x sbyte] c"math domain error\\00" """ @@ -84,6 +87,7 @@ """) + #prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ @@ -97,6 +101,20 @@ } """ % locals()) +#prepare exceptions +for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL + extfunctions["%%prepare_and_raise_%(exc)s" % locals()] = ((), """ +internal fastcc void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { + ;XXX %%msg not used right now! + %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() + %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 + %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp + store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type + store %%RPYTHON_EXCEPTION* %%exception_value, %%RPYTHON_EXCEPTION** %%last_exception_value + unwind +} +""" % locals()) + #error-checking-code Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Thu Aug 25 11:21:15 2005 @@ -147,12 +147,13 @@ assert f1() def test_math_frexp(): - py.test.skip("ll_math_frexp not implemented") from math import frexp def fn(x): - return frexp(x) + res = frexp(x) + return res[0] + float(res[1]) f = compile_function(fn, [float]) - assert f(10.123) == frexp(10.123) + res = f(10.123) + assert res == fn(10.123) def test_math_modf(): py.test.skip("ll_math_modf not implemented (next)") From rxe at codespeak.net Thu Aug 25 11:25:32 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 11:25:32 +0200 (CEST) Subject: [pypy-svn] r16449 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050825092532.0935927B6A@code1.codespeak.net> Author: rxe Date: Thu Aug 25 11:25:31 2005 New Revision: 16449 Added: pypy/dist/pypy/translator/llvm2/module/genexterns.c Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: (ericvrp/rxe) Ad hoc code to experiment with generating llvm code from C code. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 11:25:31 2005 @@ -1,7 +1,13 @@ from os.path import exists use_boehm_gc = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') +import os +import time +import types +import urllib + import py + from pypy.translator.llvm2 import build_llvm_module from pypy.translator.llvm2.database import Database from pypy.translator.llvm2.pyxwrapper import write_pyx_wrapper @@ -17,10 +23,13 @@ from pypy.translator.translator import Translator -import time function_count = {} +def get_ll(ccode): + request = urllib.urlencode({'ccode':ccode}) + return urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() + class GenLLVM(object): def __init__(self, translator, debug=True): @@ -42,7 +51,6 @@ self.db.prepare_arg_value(c) def post_setup_externs(self): - import types rtyper = self.db._translator.rtyper from pypy.translator.c.extfunc import predeclare_all @@ -54,20 +62,53 @@ for c_name, obj in decls: if isinstance(obj, lltype.LowLevelType): + print 'XXX1', c_name self.db.prepare_type(obj) elif isinstance(obj, types.FunctionType): + print 'XXX2', c_name funcptr = getfunctionptr(self.translator, obj) c = inputconst(lltype.typeOf(funcptr), funcptr) self.db.prepare_arg_value(c) - elif isinstance(lltype.typeOf(obj), lltype.Ptr): + print 'XXX3', c_name self.db.prepare_constant(lltype.typeOf(obj), obj) else: - print "XXX predeclare" , c_name, type(obj), obj - assert False + assert False, "unhandled predeclare %s %s %s" % (c_name, type(obj), obj) return decls + def generate_llfile(self, extern_decls): + # hack to get file + + genllcode = "" + + def predeclarefn(c_name, llname): + assert llname[0] == "%" + assert '\n' not in llname + return '#define\t%s\t%s' % (c_name, llname[1:]) + + for c_name, obj in extern_decls: + if isinstance(obj, lltype.LowLevelType): + pass + elif isinstance(obj, types.FunctionType): + funcptr = getfunctionptr(self.translator, obj) + c = inputconst(lltype.typeOf(funcptr), funcptr) + llname = self.db.repr_arg(c) + genllcode += predeclarefn(c_name, llname) + "\n" + #elif isinstance(lltype.typeOf(obj), lltype.Ptr): + # if isinstance(obj.TO, lltype.FuncType): + # llname = self.db.repr_constant(obj)[1] + #XXXXXXXXXXX genllcode += predeclarefn(c_name, llname) + "\n" + + j = os.path.join + p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") + genllcode += open(p).read() + print genllcode + + ll_str = get_ll(genllcode) + ll_str = ll_str.replace("%struct.", "%") + return ll_str + def replace_with_machine_words(self, s): return s.replace('UINT',self.db.get_machine_uword()).replace('INT',self.db.get_machine_word()) @@ -91,9 +132,12 @@ # post set up externs extern_decls = self.post_setup_externs() - self.db._translator.rtyper.specialize_more_blocks() + self.translator.rtyper.specialize_more_blocks() self.db.setup_all() + print self.generate_llfile(extern_decls) + #XXXXassert False + #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) #3 seconds @@ -122,6 +166,7 @@ obj = obj.TO l = "%%%s = type %s" % (c_name, self.db.repr_type(obj)) codewriter.append(l) + #XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #elif isinstance(obj, types.FunctionType): # #c.value._obj.graph.name = c_name Added: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 11:25:31 2005 @@ -0,0 +1,41 @@ +#include +#include + +#define NULL (void *) 0 + +#define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW + +struct RPyFREXP_RESULT; +struct RPyFREXP_RESULT *ll_frexp_result__Float_Signed(double, int); + +void prepare_and_raise_ValueError(char *); +void prepare_and_raise_OverflowError(char *); + +int ll_math_is_error(double x) { + if (errno == ERANGE) { + if (!x) + return 0; + prepare_and_raise_OverflowError("math range error"); + } else { + prepare_and_raise_ValueError("math domain error"); + } + return 1; +} + +#define LL_MATH_ERROR_RESET errno = 0 + +#define LL_MATH_CHECK_ERROR(x, errret) do { \ + LL_MATH_SET_ERANGE_IF_MATH_ERROR(x); \ + if (errno && ll_math_is_error(x)) \ + return errret; \ +} while(0) + + +struct RPyFREXP_RESULT* ll_math_frexp(double x) { + int expo; + double m; + LL_MATH_ERROR_RESET; + m= frexp(x, &expo); + LL_MATH_CHECK_ERROR(m, NULL); + return ll_frexp_result__Float_Signed(m, expo); +} From ludal at codespeak.net Thu Aug 25 11:25:47 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 11:25:47 +0200 (CEST) Subject: [pypy-svn] r16450 - in pypy/dist/pypy: interpreter interpreter/astcompiler interpreter/pyparser interpreter/pyparser/test translator/goal Message-ID: <20050825092547.8C87E27B70@code1.codespeak.net> Author: ludal Date: Thu Aug 25 11:25:42 2005 New Revision: 16450 Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py pypy/dist/pypy/interpreter/astcompiler/astgen.py pypy/dist/pypy/interpreter/astcompiler/future.py pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/astcompiler/symbols.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/pythonutil.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py pypy/dist/pypy/translator/goal/targetcompiler.py Log: - more refactoring of the astcompiler to make it rpython - removed multiple inheritance which was actually only single inheritance with tricks with init functions so that multiple inheritance behaved like single inheritance (yes...) - splitted emit methods into several methods with a different type of object - fixed some bug from previous refactoring (scope in symbols.py, visitors not inheriting from ASTVisitor) - removed the class members NameFinder, FunctionGen, ClassGen whose type we exactly know at the time we build the class - setlineno returning - use a stack for genexpr and listcomp fallback block instead of passing it as *arg to the visitor - removed the recently introduced visit*Const since our const now contains wrapped objects - use two visitors for augmented assignement instead of wrapping node objects into delegator nodes - introduce the space object all over the compiler - we now build wrapped objects directly into the consts tuple of code objects - we can use functions from strutil that need the space object to convert string to long objects for example - astgen.py should understand parent relationship in ast tree - this is needed to make sure that for example And.nodes and Or.nodes share the same base attribute nodes Modified: pypy/dist/pypy/interpreter/astcompiler/ast.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/ast.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/ast.py Thu Aug 25 11:25:42 2005 @@ -35,8 +35,8 @@ return self.getChildren() def getChildNodes(self): return [] # implemented by subclasses - def accept(self, visitor, *args): - return visitor.visitNode(self, *args) + def accept(self, visitor): + return visitor.visitNode(self) def flatten(self): res = [] nodes = self.getChildNodes() @@ -48,8 +48,8 @@ return res class EmptyNode(Node): - def accept(self, visitor, *args): - return visitor.visitEmptyNode(self, *args) + def accept(self, visitor): + return visitor.visitEmptyNode(self) class Expression(Node): # Expression is an artificial node class to support "eval" @@ -67,8 +67,8 @@ def __repr__(self): return "Expression(%s)" % (repr(self.node)) - def accept(self, visitor, *args): - return visitor.visitExpression(self, *args) + def accept(self, visitor): + return visitor.visitExpression(self) class Add(Node): def __init__(self, (left, right), lineno=None): @@ -85,8 +85,8 @@ def __repr__(self): return "Add((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitAdd(self, *args) + def accept(self, visitor): + return visitor.visitAdd(self) class And(Node): def __init__(self, nodes, lineno=None): @@ -104,8 +104,8 @@ def __repr__(self): return "And(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitAnd(self, *args) + def accept(self, visitor): + return visitor.visitAnd(self) class AssAttr(Node): def __init__(self, expr, attrname, flags, lineno=None): @@ -123,8 +123,8 @@ def __repr__(self): return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) - def accept(self, visitor, *args): - return visitor.visitAssAttr(self, *args) + def accept(self, visitor): + return visitor.visitAssAttr(self) class AssList(Node): def __init__(self, nodes, lineno=None): @@ -142,8 +142,8 @@ def __repr__(self): return "AssList(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitAssList(self, *args) + def accept(self, visitor): + return visitor.visitAssList(self) class AssName(Node): def __init__(self, name, flags, lineno=None): @@ -160,8 +160,8 @@ def __repr__(self): return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) - def accept(self, visitor, *args): - return visitor.visitAssName(self, *args) + def accept(self, visitor): + return visitor.visitAssName(self) class AssTuple(Node): def __init__(self, nodes, lineno=None): @@ -179,8 +179,8 @@ def __repr__(self): return "AssTuple(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitAssTuple(self, *args) + def accept(self, visitor): + return visitor.visitAssTuple(self) class Assert(Node): def __init__(self, test, fail, lineno=None): @@ -204,8 +204,8 @@ def __repr__(self): return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) - def accept(self, visitor, *args): - return visitor.visitAssert(self, *args) + def accept(self, visitor): + return visitor.visitAssert(self) class Assign(Node): def __init__(self, nodes, expr, lineno=None): @@ -228,8 +228,8 @@ def __repr__(self): return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) - def accept(self, visitor, *args): - return visitor.visitAssign(self, *args) + def accept(self, visitor): + return visitor.visitAssign(self) class AugAssign(Node): def __init__(self, node, op, expr, lineno=None): @@ -247,8 +247,8 @@ def __repr__(self): return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) - def accept(self, visitor, *args): - return visitor.visitAugAssign(self, *args) + def accept(self, visitor): + return visitor.visitAugAssign(self) class Backquote(Node): def __init__(self, expr, lineno=None): @@ -264,8 +264,8 @@ def __repr__(self): return "Backquote(%s)" % (repr(self.expr),) - def accept(self, visitor, *args): - return visitor.visitBackquote(self, *args) + def accept(self, visitor): + return visitor.visitBackquote(self) class Bitand(Node): def __init__(self, nodes, lineno=None): @@ -283,8 +283,8 @@ def __repr__(self): return "Bitand(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitBitand(self, *args) + def accept(self, visitor): + return visitor.visitBitand(self) class Bitor(Node): def __init__(self, nodes, lineno=None): @@ -302,8 +302,8 @@ def __repr__(self): return "Bitor(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitBitor(self, *args) + def accept(self, visitor): + return visitor.visitBitor(self) class Bitxor(Node): def __init__(self, nodes, lineno=None): @@ -321,8 +321,8 @@ def __repr__(self): return "Bitxor(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitBitxor(self, *args) + def accept(self, visitor): + return visitor.visitBitxor(self) class Break(Node): def __init__(self, lineno=None): @@ -337,8 +337,8 @@ def __repr__(self): return "Break()" - def accept(self, visitor, *args): - return visitor.visitBreak(self, *args) + def accept(self, visitor): + return visitor.visitBreak(self) class CallFunc(Node): def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None): @@ -369,8 +369,8 @@ def __repr__(self): return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) - def accept(self, visitor, *args): - return visitor.visitCallFunc(self, *args) + def accept(self, visitor): + return visitor.visitCallFunc(self) class Class(Node): def __init__(self, name, bases, doc, code, lineno=None): @@ -397,8 +397,8 @@ def __repr__(self): return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code)) - def accept(self, visitor, *args): - return visitor.visitClass(self, *args) + def accept(self, visitor): + return visitor.visitClass(self) class Compare(Node): def __init__(self, expr, ops, lineno=None): @@ -421,8 +421,8 @@ def __repr__(self): return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) - def accept(self, visitor, *args): - return visitor.visitCompare(self, *args) + def accept(self, visitor): + return visitor.visitCompare(self) class Const(Node): def __init__(self, value, lineno=None): @@ -438,8 +438,8 @@ def __repr__(self): return "Const(%s)" % (repr(self.value),) - def accept(self, visitor, *args): - return visitor.visitConst(self, *args) + def accept(self, visitor): + return visitor.visitConst(self) class Continue(Node): def __init__(self, lineno=None): @@ -454,8 +454,8 @@ def __repr__(self): return "Continue()" - def accept(self, visitor, *args): - return visitor.visitContinue(self, *args) + def accept(self, visitor): + return visitor.visitContinue(self) class Decorators(Node): def __init__(self, nodes, lineno=None): @@ -473,8 +473,8 @@ def __repr__(self): return "Decorators(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitDecorators(self, *args) + def accept(self, visitor): + return visitor.visitDecorators(self) class Dict(Node): def __init__(self, items, lineno=None): @@ -492,8 +492,8 @@ def __repr__(self): return "Dict(%s)" % (repr(self.items),) - def accept(self, visitor, *args): - return visitor.visitDict(self, *args) + def accept(self, visitor): + return visitor.visitDict(self) class Discard(Node): def __init__(self, expr, lineno=None): @@ -509,8 +509,8 @@ def __repr__(self): return "Discard(%s)" % (repr(self.expr),) - def accept(self, visitor, *args): - return visitor.visitDiscard(self, *args) + def accept(self, visitor): + return visitor.visitDiscard(self) class Div(Node): def __init__(self, (left, right), lineno=None): @@ -527,8 +527,8 @@ def __repr__(self): return "Div((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitDiv(self, *args) + def accept(self, visitor): + return visitor.visitDiv(self) class Ellipsis(Node): def __init__(self, lineno=None): @@ -543,8 +543,8 @@ def __repr__(self): return "Ellipsis()" - def accept(self, visitor, *args): - return visitor.visitEllipsis(self, *args) + def accept(self, visitor): + return visitor.visitEllipsis(self) class Exec(Node): def __init__(self, expr, locals, globals, lineno=None): @@ -572,8 +572,8 @@ def __repr__(self): return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) - def accept(self, visitor, *args): - return visitor.visitExec(self, *args) + def accept(self, visitor): + return visitor.visitExec(self) class FloorDiv(Node): def __init__(self, (left, right), lineno=None): @@ -590,8 +590,8 @@ def __repr__(self): return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitFloorDiv(self, *args) + def accept(self, visitor): + return visitor.visitFloorDiv(self) class For(Node): def __init__(self, assign, list, body, else_, lineno=None): @@ -621,8 +621,8 @@ def __repr__(self): return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) - def accept(self, visitor, *args): - return visitor.visitFor(self, *args) + def accept(self, visitor): + return visitor.visitFor(self) class From(Node): def __init__(self, modname, names, lineno=None): @@ -639,8 +639,8 @@ def __repr__(self): return "From(%s, %s)" % (repr(self.modname), repr(self.names)) - def accept(self, visitor, *args): - return visitor.visitFrom(self, *args) + def accept(self, visitor): + return visitor.visitFrom(self) class Function(Node): def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None): @@ -682,8 +682,8 @@ def __repr__(self): return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) - def accept(self, visitor, *args): - return visitor.visitFunction(self, *args) + def accept(self, visitor): + return visitor.visitFunction(self) class GenExpr(Node): def __init__(self, code, lineno=None): @@ -703,8 +703,8 @@ def __repr__(self): return "GenExpr(%s)" % (repr(self.code),) - def accept(self, visitor, *args): - return visitor.visitGenExpr(self, *args) + def accept(self, visitor): + return visitor.visitGenExpr(self) class GenExprFor(Node): def __init__(self, assign, iter, ifs, lineno=None): @@ -732,8 +732,8 @@ def __repr__(self): return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) - def accept(self, visitor, *args): - return visitor.visitGenExprFor(self, *args) + def accept(self, visitor): + return visitor.visitGenExprFor(self) class GenExprIf(Node): def __init__(self, test, lineno=None): @@ -749,8 +749,8 @@ def __repr__(self): return "GenExprIf(%s)" % (repr(self.test),) - def accept(self, visitor, *args): - return visitor.visitGenExprIf(self, *args) + def accept(self, visitor): + return visitor.visitGenExprIf(self) class GenExprInner(Node): def __init__(self, expr, quals, lineno=None): @@ -773,8 +773,8 @@ def __repr__(self): return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) - def accept(self, visitor, *args): - return visitor.visitGenExprInner(self, *args) + def accept(self, visitor): + return visitor.visitGenExprInner(self) class Getattr(Node): def __init__(self, expr, attrname, lineno=None): @@ -791,8 +791,8 @@ def __repr__(self): return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) - def accept(self, visitor, *args): - return visitor.visitGetattr(self, *args) + def accept(self, visitor): + return visitor.visitGetattr(self) class Global(Node): def __init__(self, names, lineno=None): @@ -808,8 +808,8 @@ def __repr__(self): return "Global(%s)" % (repr(self.names),) - def accept(self, visitor, *args): - return visitor.visitGlobal(self, *args) + def accept(self, visitor): + return visitor.visitGlobal(self) class If(Node): def __init__(self, tests, else_, lineno=None): @@ -833,8 +833,8 @@ def __repr__(self): return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) - def accept(self, visitor, *args): - return visitor.visitIf(self, *args) + def accept(self, visitor): + return visitor.visitIf(self) class Import(Node): def __init__(self, names, lineno=None): @@ -850,8 +850,8 @@ def __repr__(self): return "Import(%s)" % (repr(self.names),) - def accept(self, visitor, *args): - return visitor.visitImport(self, *args) + def accept(self, visitor): + return visitor.visitImport(self) class Invert(Node): def __init__(self, expr, lineno=None): @@ -867,8 +867,8 @@ def __repr__(self): return "Invert(%s)" % (repr(self.expr),) - def accept(self, visitor, *args): - return visitor.visitInvert(self, *args) + def accept(self, visitor): + return visitor.visitInvert(self) class Keyword(Node): def __init__(self, name, expr, lineno=None): @@ -885,8 +885,8 @@ def __repr__(self): return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) - def accept(self, visitor, *args): - return visitor.visitKeyword(self, *args) + def accept(self, visitor): + return visitor.visitKeyword(self) class Lambda(Node): def __init__(self, argnames, defaults, flags, code, lineno=None): @@ -920,8 +920,8 @@ def __repr__(self): return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) - def accept(self, visitor, *args): - return visitor.visitLambda(self, *args) + def accept(self, visitor): + return visitor.visitLambda(self) class LeftShift(Node): def __init__(self, (left, right), lineno=None): @@ -938,8 +938,8 @@ def __repr__(self): return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitLeftShift(self, *args) + def accept(self, visitor): + return visitor.visitLeftShift(self) class List(Node): def __init__(self, nodes, lineno=None): @@ -957,8 +957,8 @@ def __repr__(self): return "List(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitList(self, *args) + def accept(self, visitor): + return visitor.visitList(self) class ListComp(Node): def __init__(self, expr, quals, lineno=None): @@ -981,8 +981,8 @@ def __repr__(self): return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) - def accept(self, visitor, *args): - return visitor.visitListComp(self, *args) + def accept(self, visitor): + return visitor.visitListComp(self) class ListCompFor(Node): def __init__(self, assign, list, ifs, lineno=None): @@ -1008,8 +1008,8 @@ def __repr__(self): return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) - def accept(self, visitor, *args): - return visitor.visitListCompFor(self, *args) + def accept(self, visitor): + return visitor.visitListCompFor(self) class ListCompIf(Node): def __init__(self, test, lineno=None): @@ -1025,8 +1025,8 @@ def __repr__(self): return "ListCompIf(%s)" % (repr(self.test),) - def accept(self, visitor, *args): - return visitor.visitListCompIf(self, *args) + def accept(self, visitor): + return visitor.visitListCompIf(self) class Mod(Node): def __init__(self, (left, right), lineno=None): @@ -1043,8 +1043,8 @@ def __repr__(self): return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitMod(self, *args) + def accept(self, visitor): + return visitor.visitMod(self) class Module(Node): def __init__(self, doc, node, lineno=None): @@ -1061,8 +1061,8 @@ def __repr__(self): return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) - def accept(self, visitor, *args): - return visitor.visitModule(self, *args) + def accept(self, visitor): + return visitor.visitModule(self) class Mul(Node): def __init__(self, (left, right), lineno=None): @@ -1079,8 +1079,8 @@ def __repr__(self): return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitMul(self, *args) + def accept(self, visitor): + return visitor.visitMul(self) class Name(Node): def __init__(self, varname, lineno=None): @@ -1096,8 +1096,8 @@ def __repr__(self): return "Name(%s)" % (repr(self.varname),) - def accept(self, visitor, *args): - return visitor.visitName(self, *args) + def accept(self, visitor): + return visitor.visitName(self) class NoneConst(Node): def __init__(self, lineno=None): @@ -1112,8 +1112,8 @@ def __repr__(self): return "NoneConst()" - def accept(self, visitor, *args): - return visitor.visitNoneConst(self, *args) + def accept(self, visitor): + return visitor.visitNoneConst(self) class Not(Node): def __init__(self, expr, lineno=None): @@ -1129,8 +1129,8 @@ def __repr__(self): return "Not(%s)" % (repr(self.expr),) - def accept(self, visitor, *args): - return visitor.visitNot(self, *args) + def accept(self, visitor): + return visitor.visitNot(self) class NumberConst(Node): def __init__(self, number_value, lineno=None): @@ -1146,8 +1146,8 @@ def __repr__(self): return "NumberConst(%s)" % (repr(self.number_value),) - def accept(self, visitor, *args): - return visitor.visitNumberConst(self, *args) + def accept(self, visitor): + return visitor.visitNumberConst(self) class Or(Node): def __init__(self, nodes, lineno=None): @@ -1165,8 +1165,8 @@ def __repr__(self): return "Or(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitOr(self, *args) + def accept(self, visitor): + return visitor.visitOr(self) class Pass(Node): def __init__(self, lineno=None): @@ -1181,8 +1181,8 @@ def __repr__(self): return "Pass()" - def accept(self, visitor, *args): - return visitor.visitPass(self, *args) + def accept(self, visitor): + return visitor.visitPass(self) class Power(Node): def __init__(self, (left, right), lineno=None): @@ -1199,8 +1199,8 @@ def __repr__(self): return "Power((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitPower(self, *args) + def accept(self, visitor): + return visitor.visitPower(self) class Print(Node): def __init__(self, nodes, dest, lineno=None): @@ -1224,8 +1224,8 @@ def __repr__(self): return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) - def accept(self, visitor, *args): - return visitor.visitPrint(self, *args) + def accept(self, visitor): + return visitor.visitPrint(self) class Printnl(Node): def __init__(self, nodes, dest, lineno=None): @@ -1249,8 +1249,8 @@ def __repr__(self): return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) - def accept(self, visitor, *args): - return visitor.visitPrintnl(self, *args) + def accept(self, visitor): + return visitor.visitPrintnl(self) class Raise(Node): def __init__(self, expr1, expr2, expr3, lineno=None): @@ -1279,8 +1279,8 @@ def __repr__(self): return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) - def accept(self, visitor, *args): - return visitor.visitRaise(self, *args) + def accept(self, visitor): + return visitor.visitRaise(self) class Return(Node): def __init__(self, value, lineno=None): @@ -1296,8 +1296,8 @@ def __repr__(self): return "Return(%s)" % (repr(self.value),) - def accept(self, visitor, *args): - return visitor.visitReturn(self, *args) + def accept(self, visitor): + return visitor.visitReturn(self) class RightShift(Node): def __init__(self, (left, right), lineno=None): @@ -1314,8 +1314,8 @@ def __repr__(self): return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitRightShift(self, *args) + def accept(self, visitor): + return visitor.visitRightShift(self) class Slice(Node): def __init__(self, expr, flags, lower, upper, lineno=None): @@ -1345,8 +1345,8 @@ def __repr__(self): return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) - def accept(self, visitor, *args): - return visitor.visitSlice(self, *args) + def accept(self, visitor): + return visitor.visitSlice(self) class Sliceobj(Node): def __init__(self, nodes, lineno=None): @@ -1364,8 +1364,8 @@ def __repr__(self): return "Sliceobj(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitSliceobj(self, *args) + def accept(self, visitor): + return visitor.visitSliceobj(self) class Stmt(Node): def __init__(self, nodes, lineno=None): @@ -1383,8 +1383,8 @@ def __repr__(self): return "Stmt(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitStmt(self, *args) + def accept(self, visitor): + return visitor.visitStmt(self) class StringConst(Node): def __init__(self, string_value, lineno=None): @@ -1400,8 +1400,8 @@ def __repr__(self): return "StringConst(%s)" % (repr(self.string_value),) - def accept(self, visitor, *args): - return visitor.visitStringConst(self, *args) + def accept(self, visitor): + return visitor.visitStringConst(self) class Sub(Node): def __init__(self, (left, right), lineno=None): @@ -1418,8 +1418,8 @@ def __repr__(self): return "Sub((%s, %s))" % (repr(self.left), repr(self.right)) - def accept(self, visitor, *args): - return visitor.visitSub(self, *args) + def accept(self, visitor): + return visitor.visitSub(self) class Subscript(Node): def __init__(self, expr, flags, subs, lineno=None): @@ -1444,8 +1444,8 @@ def __repr__(self): return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) - def accept(self, visitor, *args): - return visitor.visitSubscript(self, *args) + def accept(self, visitor): + return visitor.visitSubscript(self) class TryExcept(Node): def __init__(self, body, handlers, else_, lineno=None): @@ -1472,8 +1472,8 @@ def __repr__(self): return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) - def accept(self, visitor, *args): - return visitor.visitTryExcept(self, *args) + def accept(self, visitor): + return visitor.visitTryExcept(self) class TryFinally(Node): def __init__(self, body, final, lineno=None): @@ -1490,8 +1490,8 @@ def __repr__(self): return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) - def accept(self, visitor, *args): - return visitor.visitTryFinally(self, *args) + def accept(self, visitor): + return visitor.visitTryFinally(self) class Tuple(Node): def __init__(self, nodes, lineno=None): @@ -1509,8 +1509,8 @@ def __repr__(self): return "Tuple(%s)" % (repr(self.nodes),) - def accept(self, visitor, *args): - return visitor.visitTuple(self, *args) + def accept(self, visitor): + return visitor.visitTuple(self) class UnaryAdd(Node): def __init__(self, expr, lineno=None): @@ -1526,8 +1526,8 @@ def __repr__(self): return "UnaryAdd(%s)" % (repr(self.expr),) - def accept(self, visitor, *args): - return visitor.visitUnaryAdd(self, *args) + def accept(self, visitor): + return visitor.visitUnaryAdd(self) class UnarySub(Node): def __init__(self, expr, lineno=None): @@ -1543,8 +1543,8 @@ def __repr__(self): return "UnarySub(%s)" % (repr(self.expr),) - def accept(self, visitor, *args): - return visitor.visitUnarySub(self, *args) + def accept(self, visitor): + return visitor.visitUnarySub(self) class While(Node): def __init__(self, test, body, else_, lineno=None): @@ -1571,8 +1571,8 @@ def __repr__(self): return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) - def accept(self, visitor, *args): - return visitor.visitWhile(self, *args) + def accept(self, visitor): + return visitor.visitWhile(self) class Yield(Node): def __init__(self, value, lineno=None): @@ -1588,8 +1588,8 @@ def __repr__(self): return "Yield(%s)" % (repr(self.value),) - def accept(self, visitor, *args): - return visitor.visitYield(self, *args) + def accept(self, visitor): + return visitor.visitYield(self) class ASTVisitor(object): @@ -1598,157 +1598,157 @@ It could also use to identify base type for visit arguments of AST nodes """ - def default(self, node, *args): + def default(self, node): for child in node.getChildNodes(): - child.accept(self, *args) + child.accept(self) - def visitAdd(self, node, *args): - return self.default( node, *args ) - def visitAnd(self, node, *args): - return self.default( node, *args ) - def visitAssAttr(self, node, *args): - return self.default( node, *args ) - def visitAssList(self, node, *args): - return self.default( node, *args ) - def visitAssName(self, node, *args): - return self.default( node, *args ) - def visitAssTuple(self, node, *args): - return self.default( node, *args ) - def visitAssert(self, node, *args): - return self.default( node, *args ) - def visitAssign(self, node, *args): - return self.default( node, *args ) - def visitAugAssign(self, node, *args): - return self.default( node, *args ) - def visitBackquote(self, node, *args): - return self.default( node, *args ) - def visitBitand(self, node, *args): - return self.default( node, *args ) - def visitBitor(self, node, *args): - return self.default( node, *args ) - def visitBitxor(self, node, *args): - return self.default( node, *args ) - def visitBreak(self, node, *args): - return self.default( node, *args ) - def visitCallFunc(self, node, *args): - return self.default( node, *args ) - def visitClass(self, node, *args): - return self.default( node, *args ) - def visitCompare(self, node, *args): - return self.default( node, *args ) - def visitConst(self, node, *args): - return self.default( node, *args ) - def visitContinue(self, node, *args): - return self.default( node, *args ) - def visitDecorators(self, node, *args): - return self.default( node, *args ) - def visitDict(self, node, *args): - return self.default( node, *args ) - def visitDiscard(self, node, *args): - return self.default( node, *args ) - def visitDiv(self, node, *args): - return self.default( node, *args ) - def visitEllipsis(self, node, *args): - return self.default( node, *args ) - def visitExec(self, node, *args): - return self.default( node, *args ) - def visitFloorDiv(self, node, *args): - return self.default( node, *args ) - def visitFor(self, node, *args): - return self.default( node, *args ) - def visitFrom(self, node, *args): - return self.default( node, *args ) - def visitFunction(self, node, *args): - return self.default( node, *args ) - def visitGenExpr(self, node, *args): - return self.default( node, *args ) - def visitGenExprFor(self, node, *args): - return self.default( node, *args ) - def visitGenExprIf(self, node, *args): - return self.default( node, *args ) - def visitGenExprInner(self, node, *args): - return self.default( node, *args ) - def visitGetattr(self, node, *args): - return self.default( node, *args ) - def visitGlobal(self, node, *args): - return self.default( node, *args ) - def visitIf(self, node, *args): - return self.default( node, *args ) - def visitImport(self, node, *args): - return self.default( node, *args ) - def visitInvert(self, node, *args): - return self.default( node, *args ) - def visitKeyword(self, node, *args): - return self.default( node, *args ) - def visitLambda(self, node, *args): - return self.default( node, *args ) - def visitLeftShift(self, node, *args): - return self.default( node, *args ) - def visitList(self, node, *args): - return self.default( node, *args ) - def visitListComp(self, node, *args): - return self.default( node, *args ) - def visitListCompFor(self, node, *args): - return self.default( node, *args ) - def visitListCompIf(self, node, *args): - return self.default( node, *args ) - def visitMod(self, node, *args): - return self.default( node, *args ) - def visitModule(self, node, *args): - return self.default( node, *args ) - def visitMul(self, node, *args): - return self.default( node, *args ) - def visitName(self, node, *args): - return self.default( node, *args ) - def visitNoneConst(self, node, *args): - return self.default( node, *args ) - def visitNot(self, node, *args): - return self.default( node, *args ) - def visitNumberConst(self, node, *args): - return self.default( node, *args ) - def visitOr(self, node, *args): - return self.default( node, *args ) - def visitPass(self, node, *args): - return self.default( node, *args ) - def visitPower(self, node, *args): - return self.default( node, *args ) - def visitPrint(self, node, *args): - return self.default( node, *args ) - def visitPrintnl(self, node, *args): - return self.default( node, *args ) - def visitRaise(self, node, *args): - return self.default( node, *args ) - def visitReturn(self, node, *args): - return self.default( node, *args ) - def visitRightShift(self, node, *args): - return self.default( node, *args ) - def visitSlice(self, node, *args): - return self.default( node, *args ) - def visitSliceobj(self, node, *args): - return self.default( node, *args ) - def visitStmt(self, node, *args): - return self.default( node, *args ) - def visitStringConst(self, node, *args): - return self.default( node, *args ) - def visitSub(self, node, *args): - return self.default( node, *args ) - def visitSubscript(self, node, *args): - return self.default( node, *args ) - def visitTryExcept(self, node, *args): - return self.default( node, *args ) - def visitTryFinally(self, node, *args): - return self.default( node, *args ) - def visitTuple(self, node, *args): - return self.default( node, *args ) - def visitUnaryAdd(self, node, *args): - return self.default( node, *args ) - def visitUnarySub(self, node, *args): - return self.default( node, *args ) - def visitWhile(self, node, *args): - return self.default( node, *args ) - def visitYield(self, node, *args): - return self.default( node, *args ) + def visitAdd(self, node): + return self.default( node ) + def visitAnd(self, node): + return self.default( node ) + def visitAssAttr(self, node): + return self.default( node ) + def visitAssList(self, node): + return self.default( node ) + def visitAssName(self, node): + return self.default( node ) + def visitAssTuple(self, node): + return self.default( node ) + def visitAssert(self, node): + return self.default( node ) + def visitAssign(self, node): + return self.default( node ) + def visitAugAssign(self, node): + return self.default( node ) + def visitBackquote(self, node): + return self.default( node ) + def visitBitand(self, node): + return self.default( node ) + def visitBitor(self, node): + return self.default( node ) + def visitBitxor(self, node): + return self.default( node ) + def visitBreak(self, node): + return self.default( node ) + def visitCallFunc(self, node): + return self.default( node ) + def visitClass(self, node): + return self.default( node ) + def visitCompare(self, node): + return self.default( node ) + def visitConst(self, node): + return self.default( node ) + def visitContinue(self, node): + return self.default( node ) + def visitDecorators(self, node): + return self.default( node ) + def visitDict(self, node): + return self.default( node ) + def visitDiscard(self, node): + return self.default( node ) + def visitDiv(self, node): + return self.default( node ) + def visitEllipsis(self, node): + return self.default( node ) + def visitExec(self, node): + return self.default( node ) + def visitFloorDiv(self, node): + return self.default( node ) + def visitFor(self, node): + return self.default( node ) + def visitFrom(self, node): + return self.default( node ) + def visitFunction(self, node): + return self.default( node ) + def visitGenExpr(self, node): + return self.default( node ) + def visitGenExprFor(self, node): + return self.default( node ) + def visitGenExprIf(self, node): + return self.default( node ) + def visitGenExprInner(self, node): + return self.default( node ) + def visitGetattr(self, node): + return self.default( node ) + def visitGlobal(self, node): + return self.default( node ) + def visitIf(self, node): + return self.default( node ) + def visitImport(self, node): + return self.default( node ) + def visitInvert(self, node): + return self.default( node ) + def visitKeyword(self, node): + return self.default( node ) + def visitLambda(self, node): + return self.default( node ) + def visitLeftShift(self, node): + return self.default( node ) + def visitList(self, node): + return self.default( node ) + def visitListComp(self, node): + return self.default( node ) + def visitListCompFor(self, node): + return self.default( node ) + def visitListCompIf(self, node): + return self.default( node ) + def visitMod(self, node): + return self.default( node ) + def visitModule(self, node): + return self.default( node ) + def visitMul(self, node): + return self.default( node ) + def visitName(self, node): + return self.default( node ) + def visitNoneConst(self, node): + return self.default( node ) + def visitNot(self, node): + return self.default( node ) + def visitNumberConst(self, node): + return self.default( node ) + def visitOr(self, node): + return self.default( node ) + def visitPass(self, node): + return self.default( node ) + def visitPower(self, node): + return self.default( node ) + def visitPrint(self, node): + return self.default( node ) + def visitPrintnl(self, node): + return self.default( node ) + def visitRaise(self, node): + return self.default( node ) + def visitReturn(self, node): + return self.default( node ) + def visitRightShift(self, node): + return self.default( node ) + def visitSlice(self, node): + return self.default( node ) + def visitSliceobj(self, node): + return self.default( node ) + def visitStmt(self, node): + return self.default( node ) + def visitStringConst(self, node): + return self.default( node ) + def visitSub(self, node): + return self.default( node ) + def visitSubscript(self, node): + return self.default( node ) + def visitTryExcept(self, node): + return self.default( node ) + def visitTryFinally(self, node): + return self.default( node ) + def visitTuple(self, node): + return self.default( node ) + def visitUnaryAdd(self, node): + return self.default( node ) + def visitUnarySub(self, node): + return self.default( node ) + def visitWhile(self, node): + return self.default( node ) + def visitYield(self, node): + return self.default( node ) for name, obj in globals().items(): if isinstance(obj, type) and issubclass(obj, Node): Modified: pypy/dist/pypy/interpreter/astcompiler/astgen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/astgen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/astgen.py Thu Aug 25 11:25:42 2005 @@ -43,13 +43,20 @@ class NodeInfo: """Each instance describes a specific AST node""" - def __init__(self, name, args): + def __init__(self, name, args, parent=None): self.name = name self.args = args.strip() self.argnames = self.get_argnames() self.argprops = self.get_argprops() self.nargs = len(self.argnames) self.init = [] + self.parent = parent + + def setup_parent(self, classes): + if self.parent: + self.parent = classes[self.parent] + else: + self.parent = NodeInfo("Node","") def get_argnames(self): if '(' in self.args: @@ -95,7 +102,7 @@ def gen_source(self): buf = StringIO() - print >> buf, "class %s(Node):" % self.name + print >> buf, "class %s(%s):" % (self.name, self.parent.name) self._gen_init(buf) print >> buf self._gen_getChildren(buf) @@ -109,11 +116,18 @@ return buf.read() def _gen_init(self, buf): - if self.args: - print >> buf, " def __init__(self, %s, lineno=None):" % self.args + if self.parent.args and self.args: + args = self.parent.args +","+ self.args + else: + args = self.parent.args or self.args + if args: + print >> buf, " def __init__(self, %s, lineno=None):" % args else: print >> buf, " def __init__(self, lineno=None):" - print >> buf, " Node.__init__(self, lineno)" + if self.parent.args: + print >> buf, " %s.__init__(self, %s, lineno)" % self.parent.args + else: + print >> buf, " Node.__init__(self, lineno)" if self.argnames: for name in self.argnames: print >> buf, " self.%s = %s" % (name, name) @@ -192,12 +206,12 @@ print >> buf, ' return "%s()"' % self.name def _gen_visit(self, buf): - print >> buf, " def accept(self, visitor, *args):" - print >> buf, " return visitor.visit%s(self, *args)" % self.name + print >> buf, " def accept(self, visitor):" + print >> buf, " return visitor.visit%s(self)" % self.name def gen_base_visit(self, buf): - print >> buf, " def visit%s(self, node, *args):" % self.name - print >> buf, " return self.default( node, *args )" + print >> buf, " def visit%s(self, node):" % self.name + print >> buf, " return self.default( node )" rx_init = re.compile('init\((.*)\):') @@ -215,7 +229,12 @@ name, args = line.split(':') except ValueError: continue - classes[name] = NodeInfo(name, args) + if "(" in name: + name, parent = name.split("(") + parent = parent[:-1] + else: + parent = None + classes[name] = NodeInfo(name, args, parent) cur = None else: # some code for the __init__ method @@ -224,6 +243,8 @@ # some extra code for a Node's __init__ method name = mo.group(1) cur = classes[name] + for node in classes.values(): + node.setup_parent(classes) return sorted(classes.values(), key=lambda n: n.name) ASTVISITORCLASS=''' @@ -233,9 +254,9 @@ It could also use to identify base type for visit arguments of AST nodes """ - def default(self, node, *args): + def default(self, node): for child in node.getChildNodes(): - child.accept(self, *args) + child.accept(self) ''' @@ -266,6 +287,7 @@ This file is automatically generated by Tools/compiler/astgen.py """ from consts import CO_VARARGS, CO_VARKEYWORDS, OP_ASSIGN +from pypy.interpreter.baseobjspace import Wrappable def flatten(list): l = [] @@ -283,7 +305,7 @@ nodes = {} -class Node: +class Node(Wrappable): """Abstract base class for ast nodes.""" def __init__(self, lineno = None): self.lineno = lineno @@ -298,8 +320,8 @@ return self.getChildren() def getChildNodes(self): return [] # implemented by subclasses - def accept(self, visitor, *args): - return visitor.visitNode(self, *args) + def accept(self, visitor): + return visitor.visitNode(self) def flatten(self): res = [] nodes = self.getChildNodes() @@ -310,9 +332,10 @@ res.append( self ) return res + class EmptyNode(Node): - def accept(self, visitor, *args): - return visitor.visitEmptyNode(self, *args) + def accept(self, visitor): + return visitor.visitEmptyNode(self) class Expression(Node): # Expression is an artificial node class to support "eval" @@ -330,8 +353,8 @@ def __repr__(self): return "Expression(%s)" % (repr(self.node)) - def accept(self, visitor, *args): - return visitor.visitExpression(self, *args) + def accept(self, visitor): + return visitor.visitExpression(self) ### EPILOGUE for name, obj in globals().items(): Modified: pypy/dist/pypy/interpreter/astcompiler/future.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/future.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/future.py Thu Aug 25 11:25:42 2005 @@ -13,7 +13,7 @@ else: return 0 -class FutureParser: +class FutureParser(ast.ASTVisitor): features = ("nested_scopes", "generators", "division") @@ -42,7 +42,7 @@ """Return list of features enabled by future statements""" return self.found.keys() -class BadFutureParser: +class BadFutureParser(ast.ASTVisitor): """Check for invalid future statements""" def visitFrom(self, node): Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Thu Aug 25 11:25:42 2005 @@ -1,19 +1,20 @@ """A flow graph representation for Python bytecode""" import dis -import new import sys import types -from pypy.interpreter.pycode import PyCode from pypy.interpreter.astcompiler import misc, ast from pypy.interpreter.astcompiler.consts \ import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS +from pypy.interpreter.pycode import PyCode +from pypy.interpreter.baseobjspace import W_Root class FlowGraph: - def __init__(self): - self.current = self.entry = Block() - self.exit = Block("exit") + def __init__(self, space): + self.space = space + self.current = self.entry = Block(space) + self.exit = Block(space,"exit") self.blocks = misc.Set() self.blocks.add(self.entry) self.blocks.add(self.exit) @@ -54,7 +55,7 @@ self.startBlock(block) def newBlock(self): - b = Block() + b = Block(self.space) self.blocks.add(b) return b @@ -69,14 +70,41 @@ def _disable_debug(self): self._debug = 0 - def emit(self, *inst): + def emit(self, inst): if self._debug: print "\t", inst - if inst[0] in ['RETURN_VALUE', 'YIELD_VALUE']: + if inst in ['RETURN_VALUE', 'YIELD_VALUE']: self.current.addOutEdge(self.exit) - if len(inst) == 2 and isinstance(inst[1], Block): - self.current.addOutEdge(inst[1]) - self.current.emit(inst) + self.current.emit( (inst,) ) + + def emitop(self, inst, arg ): + if self._debug: + print "\t", inst, arg + self.current.emit( (inst,arg) ) + + def emitop_obj(self, inst, obj ): + if self._debug: + print "\t", inst, repr(obj) + self.current.emit( (inst,obj) ) + + def emitop_int(self, inst, intval ): + if self._debug: + print "\t", inst, intval + assert type(intval)==int + self.current.emit( (inst,intval) ) + + def emitop_block(self, inst, block): + if self._debug: + print "\t", inst, block + assert isinstance(block, Block) + self.current.addOutEdge( block ) + self.current.emit( (inst,block) ) + + def emitop_name(self, inst, name ): + if self._debug: + print "\t", inst, name + assert type(name)==str + self.current.emit( (inst,name) ) def getBlocksInOrder(self): """Return the blocks in reverse postorder @@ -235,13 +263,14 @@ class Block: _count = BlockCounter() - def __init__(self, label=''): + def __init__(self, space, label=''): self.insts = [] self.inEdges = misc.Set() self.outEdges = misc.Set() self.label = label self.bid = Block._count.value() self.next = [] + self.space = space Block._count.inc() def __repr__(self): @@ -259,6 +288,8 @@ op = inst[0] if op[:4] == 'JUMP': self.outEdges.add(inst[1]) +## if op=="LOAD_CONST": +## assert isinstance( inst[1], W_Root ) or hasattr( inst[1], 'getCode') self.insts.append( list(inst) ) def getInstructions(self): @@ -327,13 +358,12 @@ DONE = "DONE" class PyFlowGraph(FlowGraph): - super_init = FlowGraph.__init__ - def __init__(self, name, filename, args=(), optimized=0, klass=None): - self.super_init() + def __init__(self, space, name, filename, args=(), optimized=0, klass=None): + FlowGraph.__init__(self, space) self.name = name self.filename = filename - self.docstring = None + self.docstring = space.w_None self.args = args # XXX self.argcount = getArgCount(args) self.klass = klass @@ -569,6 +599,7 @@ def _convert_LOAD_CONST(self, arg): if hasattr(arg, 'getCode'): arg = arg.getCode() +## assert arg is not None return self._lookupName(arg, self.consts) def _convert_LOAD_FAST(self, arg): @@ -662,12 +693,13 @@ argcount = argcount - 1 # was return new.code, now we just return the parameters and let # the caller create the code object - return (argcount, nlocals, self.stacksize, self.flags, - self.lnotab.getCode(), self.getConsts(), - tuple(self.names), tuple(self.varnames), - self.filename, self.name, self.lnotab.firstline, - self.lnotab.getTable(), tuple(self.freevars), - tuple(self.cellvars)) + return PyCode(self.space)._code_new_w( argcount, nlocals, + self.stacksize, self.flags, + self.lnotab.getCode(), self.getConsts(), + tuple(self.names), tuple(self.varnames), + self.filename, self.name, self.lnotab.firstline, + self.lnotab.getTable(), tuple(self.freevars), + tuple(self.cellvars)) def getConsts(self): """Return a tuple for the const slot of the code object Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Thu Aug 25 11:25:42 2005 @@ -13,6 +13,7 @@ from pypy.interpreter.astcompiler.consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pypy.interpreter.astcompiler.pyassem import TupleArg +from pypy.interpreter.pyparser.error import SyntaxError # drop VERSION dependency since it the ast transformer for 2.4 doesn't work with 2.3 anyway VERSION = 2 @@ -188,12 +189,14 @@ __initialized = None class_name = None # provide default for instance variable - def __init__(self): + def __init__(self, space): + self.space = space self.checkClass() self.locals = misc.Stack() self.setups = misc.Stack() self.last_lineno = None self._div_op = "BINARY_DIVIDE" + self.genexpr_cont_stack = [] # XXX set flags based on future features futures = self.get_module().futures @@ -208,16 +211,26 @@ """Verify that class is constructed correctly""" try: assert hasattr(self, 'graph') - assert getattr(self, 'NameFinder') - assert getattr(self, 'FunctionGen') - assert getattr(self, 'ClassGen') except AssertionError, msg: intro = "Bad class construction for %s" % self.__class__.__name__ raise AssertionError, intro - def emit(self, *inst ): - return self.graph.emit( *inst ) + def emit(self, inst ): + return self.graph.emit( inst ) + + def emitop(self, inst, op): + return self.graph.emitop_name( inst, op ) + + def emitop_obj(self, inst, obj): + return self.graph.emitop_obj( inst, obj ) + + def emitop_int(self, inst, op): + assert type(op) == int + return self.graph.emitop_int( inst, op ) + + def emitop_block(self, inst, block): + return self.graph.emitop_block( inst, block ) def nextBlock(self, block=None ): """graph delegation""" @@ -272,18 +285,18 @@ scope = self.scope.check_name(name) if scope == SC_LOCAL: if not self.optimized: - self.emit(prefix + '_NAME', name) + self.emitop(prefix + '_NAME', name) else: - self.emit(prefix + '_FAST', name) + self.emitop(prefix + '_FAST', name) elif scope == SC_GLOBAL: if not self.optimized: - self.emit(prefix + '_NAME', name) + self.emitop(prefix + '_NAME', name) else: - self.emit(prefix + '_GLOBAL', name) + self.emitop(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: - self.emit(prefix + '_DEREF', name) + self.emitop(prefix + '_DEREF', name) elif scope == SC_REALLY_GLOBAL: - self.emit(prefix + '_GLOBAL', name) + self.emitop(prefix + '_GLOBAL', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) @@ -296,9 +309,9 @@ they aren't present in the program text. """ if self.optimized: - self.emit(prefix + '_FAST', name) + self.emitop(prefix + '_FAST', name) else: - self.emit(prefix + '_NAME', name) + self.emitop(prefix + '_NAME', name) # The set_lineno() function and the explicit emit() calls for # SET_LINENO below are only used to generate the line number table. @@ -319,10 +332,12 @@ and a consistent policy implemented and documented. Until then, this method works around missing line numbers. """ + if node is None: + return False lineno = node.lineno if lineno is not None and (lineno != self.last_lineno or force): - self.emit('SET_LINENO', lineno) + self.emitop_int('SET_LINENO', lineno) self.last_lineno = lineno return True return False @@ -331,21 +346,19 @@ # code objects. They use class attributes to determine what # specialized code generators to use. - NameFinder = LocalNameFinder - FunctionGen = None - ClassGen = None def visitModule(self, node): self.scopes = self.parseSymbols(node) self.scope = self.scopes[node] - self.emit('SET_LINENO', 0) + self.emitop_int('SET_LINENO', 0) if node.doc: - self.emit('LOAD_CONST', node.doc) + self.emitop_obj('LOAD_CONST', node.doc) self.storeName('__doc__') - lnf = walk(node.node, self.NameFinder(), verbose=0) + lnf = LocalNameFinder() + node.node.accept(lnf) self.locals.push(lnf.getLocals()) node.node.accept( self ) - self.emit('LOAD_CONST', None) + self.emitop_obj('LOAD_CONST', self.space.w_None ) self.emit('RETURN_VALUE') def visitExpression(self, node): @@ -372,7 +385,7 @@ else: ndecorators = 0 - gen = self.FunctionGen(node, self.scopes, isLambda, + gen = FunctionCodeGenerator(self.space, node, self.scopes, isLambda, self.class_name, self.get_module()) walk(node.code, gen) gen.finish() @@ -382,35 +395,35 @@ frees = gen.scope.get_free_vars() if frees: for name in frees: - self.emit('LOAD_CLOSURE', name) - self.emit('LOAD_CONST', gen) - self.emit('MAKE_CLOSURE', len(node.defaults)) + self.emitop('LOAD_CLOSURE', name) + self.emitop_obj('LOAD_CONST', gen) + self.emitop_int('MAKE_CLOSURE', len(node.defaults)) else: - self.emit('LOAD_CONST', gen) - self.emit('MAKE_FUNCTION', len(node.defaults)) + self.emitop_obj('LOAD_CONST', gen) + self.emitop_int('MAKE_FUNCTION', len(node.defaults)) for i in range(ndecorators): - self.emit('CALL_FUNCTION', 1) + self.emitop_int('CALL_FUNCTION', 1) def visitClass(self, node): - gen = self.ClassGen(node, self.scopes, - self.get_module()) + gen = ClassCodeGenerator(self.space, node, self.scopes, + self.get_module()) walk(node.code, gen) gen.finish() self.set_lineno(node) - self.emit('LOAD_CONST', node.name) + self.emitop_obj('LOAD_CONST', self.space.wrap(node.name) ) for base in node.bases: base.accept( self ) - self.emit('BUILD_TUPLE', len(node.bases)) + self.emitop_int('BUILD_TUPLE', len(node.bases)) frees = gen.scope.get_free_vars() for name in frees: - self.emit('LOAD_CLOSURE', name) - self.emit('LOAD_CONST', gen) + self.emitop('LOAD_CLOSURE', name) + self.emitop_obj('LOAD_CONST', gen) if frees: - self.emit('MAKE_CLOSURE', 0) + self.emitop_int('MAKE_CLOSURE', 0) else: - self.emit('MAKE_FUNCTION', 0) - self.emit('CALL_FUNCTION', 0) + self.emitop_int('MAKE_FUNCTION', 0) + self.emitop_int('CALL_FUNCTION', 0) self.emit('BUILD_CLASS') self.storeName(node.name) @@ -420,20 +433,18 @@ def visitIf(self, node): end = self.newBlock() - numtests = len(node.tests) - for i in range(numtests): - test, suite = node.tests[i] + for test, suite in node.tests: if is_constant_false(test): # XXX will need to check generator stuff here continue self.set_lineno(test) test.accept( self ) nextTest = self.newBlock() - self.emit('JUMP_IF_FALSE', nextTest) + self.emitop_block('JUMP_IF_FALSE', nextTest) self.nextBlock() self.emit('POP_TOP') suite.accept( self ) - self.emit('JUMP_FORWARD', end) + self.emitop_block('JUMP_FORWARD', end) self.startBlock(nextTest) self.emit('POP_TOP') if node.else_: @@ -447,19 +458,19 @@ else_ = self.newBlock() after = self.newBlock() - self.emit('SETUP_LOOP', after) + self.emitop_block('SETUP_LOOP', after) self.nextBlock(loop) self.setups.push((LOOP, loop)) self.set_lineno(node, force=True) node.test.accept( self ) - self.emit('JUMP_IF_FALSE', else_ or after) + self.emitop_block('JUMP_IF_FALSE', else_ or after) self.nextBlock() self.emit('POP_TOP') node.body.accept( self ) - self.emit('JUMP_ABSOLUTE', loop) + self.emitop_block('JUMP_ABSOLUTE', loop) self.startBlock(else_) # or just the POPs if not else clause self.emit('POP_TOP') @@ -476,16 +487,16 @@ self.setups.push((LOOP, start)) self.set_lineno(node) - self.emit('SETUP_LOOP', after) + self.emitop_block('SETUP_LOOP', after) node.list.accept( self ) self.emit('GET_ITER') self.nextBlock(start) self.set_lineno(node, force=1) - self.emit('FOR_ITER', anchor) + self.emitop_block('FOR_ITER', anchor) node.assign.accept( self ) node.body.accept( self ) - self.emit('JUMP_ABSOLUTE', start) + self.emitop_block('JUMP_ABSOLUTE', start) self.nextBlock(anchor) self.emit('POP_BLOCK') self.setups.pop() @@ -495,51 +506,56 @@ def visitBreak(self, node): if not self.setups: - raise SyntaxError, "'break' outside loop (%s, %d)" % \ - (node.filename, node.lineno) + raise SyntaxError( "'break' outside loop (%s, %d)" % + (node.filename, node.lineno) ) self.set_lineno(node) self.emit('BREAK_LOOP') def visitContinue(self, node): if not self.setups: - raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) + raise SyntaxError( "'continue' not properly in loop" + # (%s, %d)" % (node.filename, node.lineno) + ) kind, block = self.setups.top() if kind == LOOP: self.set_lineno(node) - self.emit('JUMP_ABSOLUTE', block) + self.emitop_block('JUMP_ABSOLUTE', block) self.nextBlock() elif kind == EXCEPT or kind == TRY_FINALLY: self.set_lineno(node) # find the block that starts the loop top = len(self.setups) + loop_block = None while top > 0: top = top - 1 kind, loop_block = self.setups[top] if kind == LOOP: break if kind != LOOP: - raise SyntaxError, "'continue' not properly in loop" # (%s, %d)" % (node.filename, node.lineno) - self.emit('CONTINUE_LOOP', loop_block) + raise SyntaxError( "'continue' not properly in loop" + # (%s, %d)" % (node.filename, node.lineno) + ) + self.emitop_block('CONTINUE_LOOP', loop_block) self.nextBlock() elif kind == END_FINALLY: msg = "'continue' not supported inside 'finally' clause" # " (%s, %d)" - raise SyntaxError, msg # % (node.filename, node.lineno) + raise SyntaxError( msg ) # % (node.filename, node.lineno) - def visitTest(self, node, jump): + def _visitTest(self, node, jump): end = self.newBlock() for child in node.nodes[:-1]: child.accept( self ) - self.emit(jump, end) + self.emitop_block(jump, end) self.nextBlock() self.emit('POP_TOP') node.nodes[-1].accept( self ) self.nextBlock(end) def visitAnd(self, node): - self.visitTest(node, 'JUMP_IF_FALSE') + self._visitTest(node, 'JUMP_IF_FALSE') def visitOr(self, node): - self.visitTest(node, 'JUMP_IF_TRUE') + self._visitTest(node, 'JUMP_IF_TRUE') def visitCompare(self, node): node.expr.accept( self ) @@ -548,18 +564,18 @@ code.accept( self ) self.emit('DUP_TOP') self.emit('ROT_THREE') - self.emit('COMPARE_OP', op) - self.emit('JUMP_IF_FALSE', cleanup) + self.emitop('COMPARE_OP', op) + self.emitop_block('JUMP_IF_FALSE', cleanup) self.nextBlock() self.emit('POP_TOP') # now do the last comparison if node.ops: op, code = node.ops[-1] code.accept( self ) - self.emit('COMPARE_OP', op) + self.emitop('COMPARE_OP', op) if len(node.ops) > 1: end = self.newBlock() - self.emit('JUMP_FORWARD', end) + self.emitop_block('JUMP_FORWARD', end) self.startBlock(cleanup) self.emit('ROT_TWO') self.emit('POP_TOP') @@ -573,34 +589,36 @@ # setup list append = "$append%d" % self.__list_count self.__list_count = self.__list_count + 1 - self.emit('BUILD_LIST', 0) + self.emitop_int('BUILD_LIST', 0) self.emit('DUP_TOP') - self.emit('LOAD_ATTR', 'append') + self.emitop('LOAD_ATTR', 'append') self._implicitNameOp('STORE', append) + stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): start, anchor = for_.accept( self ) - cont = None + self.genexpr_cont_stack.append( None ) for if_ in for_.ifs: - if cont is None: - cont = self.newBlock() - if_.accept( self, cont) - stack.insert(0, (start, cont, anchor)) + if self.genexpr_cont_stack[-1] is None: + self.genexpr_cont_stack[-1] = self.newBlock() + if_.accept( self ) + stack.insert(0, (start, self.genexpr_cont_stack[-1], anchor)) + self.genexpr_cont_stack.pop() self._implicitNameOp('LOAD', append) node.expr.accept( self ) - self.emit('CALL_FUNCTION', 1) + self.emitop_int('CALL_FUNCTION', 1) self.emit('POP_TOP') for start, cont, anchor in stack: if cont: skip_one = self.newBlock() - self.emit('JUMP_FORWARD', skip_one) + self.emitop_block('JUMP_FORWARD', skip_one) self.startBlock(cont) self.emit('POP_TOP') self.nextBlock(skip_one) - self.emit('JUMP_ABSOLUTE', start) + self.emitop_block('JUMP_ABSOLUTE', start) self.startBlock(anchor) self._implicitNameOp('DELETE', append) @@ -614,20 +632,21 @@ self.emit('GET_ITER') self.nextBlock(start) self.set_lineno(node, force=True) - self.emit('FOR_ITER', anchor) + self.emitop_block('FOR_ITER', anchor) self.nextBlock() node.assign.accept( self ) return start, anchor - def visitListCompIf(self, node, branch): + def visitListCompIf(self, node): + branch = self.genexpr_cont_stack[-1] self.set_lineno(node, force=True) node.test.accept( self ) - self.emit('JUMP_IF_FALSE', branch) + self.emitop_block('JUMP_IF_FALSE', branch) self.newBlock() self.emit('POP_TOP') def visitGenExpr(self, node): - gen = GenExprCodeGenerator(node, self.scopes, self.class_name, + gen = GenExprCodeGenerator(self.space, node, self.scopes, self.class_name, self.get_module()) walk(node.code, gen) gen.finish() @@ -635,17 +654,17 @@ frees = gen.scope.get_free_vars() if frees: for name in frees: - self.emit('LOAD_CLOSURE', name) - self.emit('LOAD_CONST', gen) - self.emit('MAKE_CLOSURE', 0) + self.emitop('LOAD_CLOSURE', name) + self.emitop_obj('LOAD_CONST', gen) + self.emitop_int('MAKE_CLOSURE', 0) else: - self.emit('LOAD_CONST', gen) - self.emit('MAKE_FUNCTION', 0) + self.emitop_obj('LOAD_CONST', gen) + self.emitop_int('MAKE_FUNCTION', 0) # precomputation of outmost iterable node.code.quals[0].iter.accept( self ) self.emit('GET_ITER') - self.emit('CALL_FUNCTION', 1) + self.emitop_int('CALL_FUNCTION', 1) def visitGenExprInner(self, node): self.set_lineno(node) @@ -654,12 +673,13 @@ stack = [] for i, for_ in zip(range(len(node.quals)), node.quals): start, anchor = for_.accept( self ) - cont = None + self.genexpr_cont_stack.append( None ) for if_ in for_.ifs: - if cont is None: - cont = self.newBlock() - if_.accept( self, cont) - stack.insert(0, (start, cont, anchor)) + if self.genexpr_cont_stack[-1] is None: + self.genexpr_cont_stack[-1] = self.newBlock() + if_.accept( self ) + stack.insert(0, (start, self.genexpr_cont_stack[-1], anchor)) + self.genexpr_cont_stack.pop() node.expr.accept( self ) self.emit('YIELD_VALUE') @@ -667,13 +687,13 @@ for start, cont, anchor in stack: if cont: skip_one = self.newBlock() - self.emit('JUMP_FORWARD', skip_one) + self.emitop_block('JUMP_FORWARD', skip_one) self.startBlock(cont) self.emit('POP_TOP') self.nextBlock(skip_one) - self.emit('JUMP_ABSOLUTE', start) + self.emitop_block('JUMP_ABSOLUTE', start) self.startBlock(anchor) - self.emit('LOAD_CONST', None) + self.emitop_obj('LOAD_CONST', self.space.w_None) def visitGenExprFor(self, node): start = self.newBlock() @@ -687,15 +707,16 @@ self.nextBlock(start) self.set_lineno(node, force=True) - self.emit('FOR_ITER', anchor) + self.emitop_block('FOR_ITER', anchor) self.nextBlock() node.assign.accept( self ) return start, anchor - def visitGenExprIf(self, node, branch): + def visitGenExprIf(self, node ): + branch = self.genexpr_cont_stack[-1] self.set_lineno(node, force=True) node.test.accept( self ) - self.emit('JUMP_IF_FALSE', branch) + self.emitop_block('JUMP_IF_FALSE', branch) self.newBlock() self.emit('POP_TOP') @@ -712,15 +733,15 @@ # is a sort of renaming op. self.nextBlock() node.test.accept( self ) - self.emit('JUMP_IF_TRUE', end) + self.emitop_block('JUMP_IF_TRUE', end) self.nextBlock() self.emit('POP_TOP') - self.emit('LOAD_GLOBAL', 'AssertionError') + self.emitop('LOAD_GLOBAL', 'AssertionError') if node.fail: node.fail.accept( self ) - self.emit('RAISE_VARARGS', 2) + self.emitop_int('RAISE_VARARGS', 2) else: - self.emit('RAISE_VARARGS', 1) + self.emitop_int('RAISE_VARARGS', 1) self.nextBlock(end) self.emit('POP_TOP') @@ -736,7 +757,7 @@ if node.expr3: node.expr3.accept( self ) n = n + 1 - self.emit('RAISE_VARARGS', n) + self.emitop_int('RAISE_VARARGS', n) def visitTryExcept(self, node): body = self.newBlock() @@ -747,27 +768,29 @@ else: lElse = end self.set_lineno(node) - self.emit('SETUP_EXCEPT', handlers) + self.emitop_block('SETUP_EXCEPT', handlers) self.nextBlock(body) self.setups.push((EXCEPT, body)) node.body.accept( self ) self.emit('POP_BLOCK') self.setups.pop() - self.emit('JUMP_FORWARD', lElse) + self.emitop_block('JUMP_FORWARD', lElse) self.startBlock(handlers) last = len(node.handlers) - 1 - for i in range(len(node.handlers)): - expr, target, body = node.handlers[i] - self.set_lineno(expr) + next = None + for expr, target, body in node.handlers: if expr: + self.set_lineno(expr) self.emit('DUP_TOP') expr.accept( self ) - self.emit('COMPARE_OP', 'exception match') + self.emitop('COMPARE_OP', 'exception match') next = self.newBlock() - self.emit('JUMP_IF_FALSE', next) + self.emitop_block('JUMP_IF_FALSE', next) self.nextBlock() self.emit('POP_TOP') + else: + next = None self.emit('POP_TOP') if target: target.accept( self ) @@ -775,11 +798,8 @@ self.emit('POP_TOP') self.emit('POP_TOP') body.accept( self ) - self.emit('JUMP_FORWARD', end) - if expr: - self.nextBlock(next) - else: - self.nextBlock() + self.emitop_block('JUMP_FORWARD', end) + self.nextBlock(next) if expr: # XXX self.emit('POP_TOP') self.emit('END_FINALLY') @@ -792,13 +812,13 @@ body = self.newBlock() final = self.newBlock() self.set_lineno(node) - self.emit('SETUP_FINALLY', final) + self.emitop_block('SETUP_FINALLY', final) self.nextBlock(body) self.setups.push((TRY_FINALLY, body)) node.body.accept( self ) self.emit('POP_BLOCK') self.setups.pop() - self.emit('LOAD_CONST', None) + self.emitop_obj('LOAD_CONST', self.space.w_None) self.nextBlock(final) self.setups.push((END_FINALLY, final)) node.final.accept( self ) @@ -813,19 +833,10 @@ self.emit('POP_TOP') def visitConst(self, node): - self.emit('LOAD_CONST', node.value) - - def visitNoneConst(self, node): - self.emit('LOAD_CONST', None) - - def visitNumberConst(self, node): - self.emit('LOAD_CONST', node.number_value) - - def visitStringConst(self, node): - self.emit('LOAD_CONST', node.string_value) + self.emitop_obj('LOAD_CONST', node.value) def visitKeyword(self, node): - self.emit('LOAD_CONST', node.name) + self.emitop_obj('LOAD_CONST', self.space.wrap(node.name) ) node.expr.accept( self ) def visitGlobal(self, node): @@ -842,8 +853,8 @@ def visitImport(self, node): self.set_lineno(node) for name, alias in node.names: - self.emit('LOAD_CONST', None) - self.emit('IMPORT_NAME', name) + self.emitop_obj('LOAD_CONST', self.space.w_None) + self.emitop('IMPORT_NAME', name) mod = name.split(".")[0] if alias: self._resolveDots(name) @@ -853,9 +864,9 @@ def visitFrom(self, node): self.set_lineno(node) - fromlist = map(lambda (name, alias): name, node.names) - self.emit('LOAD_CONST', tuple(fromlist)) - self.emit('IMPORT_NAME', node.modname) + fromlist = [ self.space.wrap(name) for name,alias in node.names ] + self.emitop_obj('LOAD_CONST', self.space.newtuple(fromlist)) + self.emitop('IMPORT_NAME', node.modname) for name, alias in node.names: if name == '*': self.namespace = 0 @@ -864,7 +875,7 @@ assert len(node.names) == 1 return else: - self.emit('IMPORT_FROM', name) + self.emitop('IMPORT_FROM', name) self._resolveDots(name) self.storeName(alias or name) self.emit('POP_TOP') @@ -874,11 +885,11 @@ if len(elts) == 1: return for elt in elts[1:]: - self.emit('LOAD_ATTR', elt) + self.emitop('LOAD_ATTR', elt) def visitGetattr(self, node): node.expr.accept( self ) - self.emit('LOAD_ATTR', self.mangle(node.attrname)) + self.emitop('LOAD_ATTR', self.mangle(node.attrname)) # next five implement assignments @@ -905,38 +916,30 @@ def visitAssAttr(self, node): node.expr.accept( self ) if node.flags == 'OP_ASSIGN': - self.emit('STORE_ATTR', self.mangle(node.attrname)) + self.emitop('STORE_ATTR', self.mangle(node.attrname)) elif node.flags == 'OP_DELETE': - self.emit('DELETE_ATTR', self.mangle(node.attrname)) + self.emitop('DELETE_ATTR', self.mangle(node.attrname)) else: print "warning: unexpected flags:", node.flags print node def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'): if findOp(node) != 'OP_DELETE': - self.emit(op, len(node.nodes)) + self.emitop_int(op, len(node.nodes)) for child in node.nodes: child.accept( self ) - if VERSION > 1: - visitAssTuple = _visitAssSequence - visitAssList = _visitAssSequence - else: - def visitAssTuple(self, node): - self._visitAssSequence(node, 'UNPACK_TUPLE') - - def visitAssList(self, node): - self._visitAssSequence(node, 'UNPACK_LIST') + visitAssTuple = _visitAssSequence + visitAssList = _visitAssSequence # augmented assignment def visitAugAssign(self, node): self.set_lineno(node) - aug_node = wrap_aug(node.node) - aug_node.accept( self, "load") + node.node.accept( AugLoadVisitor(self) ) node.expr.accept( self ) self.emit(self._augmented_opcode[node.op]) - aug_node.accept( self, "store") + node.node.accept( AugStoreVisitor(self) ) _augmented_opcode = { '+=' : 'INPLACE_ADD', @@ -953,51 +956,10 @@ '|=' : 'INPLACE_OR', } - def visitAugName(self, node, mode): - if mode == "load": - self.loadName(node.name) - elif mode == "store": - self.storeName(node.name) - - def visitAugGetattr(self, node, mode): - if mode == "load": - node.expr.accept( self ) - self.emit('DUP_TOP') - self.emit('LOAD_ATTR', self.mangle(node.attrname)) - elif mode == "store": - self.emit('ROT_TWO') - self.emit('STORE_ATTR', self.mangle(node.attrname)) - - def visitAugSlice(self, node, mode): - if mode == "load": - self.visitSlice(node, 1) - elif mode == "store": - slice = 0 - if node.lower: - slice = slice | 1 - if node.upper: - slice = slice | 2 - if slice == 0: - self.emit('ROT_TWO') - elif slice == 3: - self.emit('ROT_FOUR') - else: - self.emit('ROT_THREE') - self.emit('STORE_SLICE+%d' % slice) - - def visitAugSubscript(self, node, mode): - if len(node.subs) > 1: - raise SyntaxError, "augmented assignment to tuple is not possible" - if mode == "load": - self.visitSubscript(node, 1) - elif mode == "store": - self.emit('ROT_THREE') - self.emit('STORE_SUBSCR') - def visitExec(self, node): node.expr.accept( self ) if node.locals is None: - self.emit('LOAD_CONST', None) + self.emitop_obj('LOAD_CONST', self.space.w_None) else: node.locals.accept( self ) if node.globals is None: @@ -1024,7 +986,7 @@ have_star = node.star_args is not None have_dstar = node.dstar_args is not None opcode = callfunc_opcode_info[have_star, have_dstar] - self.emit(opcode, kw << 8 | pos) + self.emitop_int(opcode, kw << 8 | pos) def visitPrint(self, node, newline=0): self.set_lineno(node) @@ -1075,9 +1037,9 @@ if slice == 0: self.emit('DUP_TOP') elif slice == 3: - self.emit('DUP_TOPX', 3) + self.emitop_int('DUP_TOPX', 3) else: - self.emit('DUP_TOPX', 2) + self.emitop_int('DUP_TOPX', 2) if node.flags == 'OP_APPLY': self.emit('SLICE+%d' % slice) elif node.flags == 'OP_ASSIGN': @@ -1093,9 +1055,9 @@ for sub in node.subs: sub.accept( self ) if aug_flag: - self.emit('DUP_TOPX', 2) + self.emitop_int('DUP_TOPX', 2) if len(node.subs) > 1: - self.emit('BUILD_TUPLE', len(node.subs)) + self.emitop_int('BUILD_TUPLE', len(node.subs)) if node.flags == 'OP_APPLY': self.emit('BINARY_SUBSCR') elif node.flags == 'OP_ASSIGN': @@ -1181,28 +1143,28 @@ # object constructors def visitEllipsis(self, node): - self.emit('LOAD_CONST', Ellipsis) + self.emitop_obj('LOAD_CONST', self.space.wrap(Ellipsis) ) def visitTuple(self, node): self.set_lineno(node) for elt in node.nodes: elt.accept( self ) - self.emit('BUILD_TUPLE', len(node.nodes)) + self.emitop_int('BUILD_TUPLE', len(node.nodes)) def visitList(self, node): self.set_lineno(node) for elt in node.nodes: elt.accept( self ) - self.emit('BUILD_LIST', len(node.nodes)) + self.emitop_int('BUILD_LIST', len(node.nodes)) def visitSliceobj(self, node): for child in node.nodes: child.accept( self ) - self.emit('BUILD_SLICE', len(node.nodes)) + self.emitop_int('BUILD_SLICE', len(node.nodes)) def visitDict(self, node): self.set_lineno(node) - self.emit('BUILD_MAP', 0) + self.emitop_int('BUILD_MAP', 0) for k, v in node.items: self.emit('DUP_TOP') k.accept( self ) @@ -1212,43 +1174,42 @@ class ModuleCodeGenerator(CodeGenerator): - __super_init = CodeGenerator.__init__ - scopes = None - def __init__(self, tree): - self.graph = pyassem.PyFlowGraph("", tree.filename) + def __init__(self, space, tree, futures = []): + self.graph = pyassem.PyFlowGraph(space, "", tree.filename) self.futures = future.find_futures(tree) - self.__super_init() + for f in futures: + if f not in self.futures: + self.futures.append(f) + CodeGenerator.__init__(self, space) walk(tree, self) def get_module(self): return self class ExpressionCodeGenerator(CodeGenerator): - __super_init = CodeGenerator.__init__ - scopes = None - futures = () - def __init__(self, tree): - self.graph = pyassem.PyFlowGraph("", tree.filename) - self.__super_init() + def __init__(self, space, tree, futures=[]): + self.graph = pyassem.PyFlowGraph(space, "", tree.filename) + self.futures = futures[:] + CodeGenerator.__init__(self, space) walk(tree, self) def get_module(self): return self class InteractiveCodeGenerator(CodeGenerator): - - __super_init = CodeGenerator.__init__ - scopes = None - futures = () - def __init__(self, tree): - self.graph = pyassem.PyFlowGraph("", tree.filename) - self.__super_init() + def __init__(self, space, tree, futures=[]): + self.graph = pyassem.PyFlowGraph(space, "", tree.filename) + self.futures = future.find_futures(tree) + for f in futures: + if f not in self.futures: + self.futures.append(f) + CodeGenerator.__init__(self, space) self.set_lineno(tree) walk(tree, self) self.emit('RETURN_VALUE') @@ -1262,11 +1223,11 @@ node.expr.accept( self ) self.emit('PRINT_EXPR') -class AbstractFunctionCode: +class AbstractFunctionCode(CodeGenerator): optimized = 1 lambdaCount = 0 - def __init__(self, func, scopes, isLambda, class_name, mod): + def __init__(self, space, func, scopes, isLambda, class_name, mod): self.class_name = class_name self.module = mod if isLambda: @@ -1277,15 +1238,16 @@ name = func.name args, hasTupleArg = generateArgList(func.argnames) - self.graph = pyassem.PyFlowGraph(name, func.filename, args, + self.graph = pyassem.PyFlowGraph(space, name, func.filename, args, optimized=1) self.isLambda = isLambda - self.super_init() + CodeGenerator.__init__(self, space) if not isLambda and func.doc: self.setDocstring(func.doc) - lnf = walk(func.code, self.NameFinder(args), verbose=0) + lnf = LocalNameFinder(args) + func.code.accept(lnf) self.locals.push(lnf.getLocals()) if func.varargs: self.graph.setFlag(CO_VARARGS) @@ -1301,21 +1263,21 @@ def finish(self): self.graph.startExitBlock() if not self.isLambda: - self.emit('LOAD_CONST', None) + self.emitop_obj('LOAD_CONST', self.space.w_None) self.emit('RETURN_VALUE') def generateArgUnpack(self, args): for i in range(len(args)): arg = args[i] if isinstance(arg, ast.AssTuple): - self.emit('LOAD_FAST', '.%d' % (i * 2)) + self.emitop('LOAD_FAST', '.%d' % (i * 2)) self.unpackSequence(arg) def unpackSequence(self, tup): if VERSION > 1: - self.emit('UNPACK_SEQUENCE', len(tup.nodes)) + self.emitop_int('UNPACK_SEQUENCE', len(tup.nodes)) else: - self.emit('UNPACK_TUPLE', len(tup.nodes)) + self.emitop_int('UNPACK_TUPLE', len(tup.nodes)) for elt in tup.nodes: if isinstance(elt, ast.AssName): @@ -1327,46 +1289,39 @@ unpackTuple = unpackSequence -class FunctionCodeGenerator(AbstractFunctionCode, - CodeGenerator): - super_init = CodeGenerator.__init__ # call be other init +class FunctionCodeGenerator(AbstractFunctionCode): scopes = None - __super_init = AbstractFunctionCode.__init__ - - def __init__(self, func, scopes, isLambda, class_name, mod): + def __init__(self, space, func, scopes, isLambda, class_name, mod): self.scopes = scopes self.scope = scopes[func] - self.__super_init(func, scopes, isLambda, class_name, mod) + AbstractFunctionCode.__init__(self, space, func, scopes, isLambda, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) if self.scope.generator is not None: self.graph.setFlag(CO_GENERATOR) -class GenExprCodeGenerator(AbstractFunctionCode, - CodeGenerator): - super_init = CodeGenerator.__init__ # call be other init +class GenExprCodeGenerator(AbstractFunctionCode): scopes = None - __super_init = AbstractFunctionCode.__init__ - - def __init__(self, gexp, scopes, class_name, mod): + def __init__(self, space, gexp, scopes, class_name, mod): self.scopes = scopes self.scope = scopes[gexp] - self.__super_init(gexp, scopes, 1, class_name, mod) + AbstractFunctionCode.__init__(self, space, gexp, scopes, 1, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) self.graph.setFlag(CO_GENERATOR) -class AbstractClassCode: +class AbstractClassCode(CodeGenerator): - def __init__(self, klass, scopes, module): + def __init__(self, space, klass, scopes, module): self.class_name = klass.name self.module = module - self.graph = pyassem.PyFlowGraph(klass.name, klass.filename, + self.graph = pyassem.PyFlowGraph( space, klass.name, klass.filename, optimized=0, klass=1) - self.super_init() - lnf = walk(klass.code, self.NameFinder(), verbose=0) + CodeGenerator.__init__(self, space) + lnf = LocalNameFinder() + klass.code.accept(lnf) self.locals.push(lnf.getLocals()) self.graph.setFlag(CO_NEWLOCALS) if klass.doc: @@ -1380,23 +1335,20 @@ self.emit('LOAD_LOCALS') self.emit('RETURN_VALUE') -class ClassCodeGenerator(AbstractClassCode, CodeGenerator): - super_init = CodeGenerator.__init__ +class ClassCodeGenerator(AbstractClassCode): scopes = None - __super_init = AbstractClassCode.__init__ - - def __init__(self, klass, scopes, module): + def __init__(self, space, klass, scopes, module): self.scopes = scopes self.scope = scopes[klass] - self.__super_init(klass, scopes, module) + AbstractClassCode.__init__(self, space, klass, scopes, module) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) self.set_lineno(klass) - self.emit("LOAD_GLOBAL", "__name__") + self.emitop("LOAD_GLOBAL", "__name__") self.storeName("__module__") if klass.doc: - self.emit("LOAD_CONST", klass.doc) + self.emitop_obj("LOAD_CONST", klass.doc) self.storeName('__doc__') def generateArgList(arglist): @@ -1433,53 +1385,65 @@ visitAssAttr = visitAssName visitSubscript = visitAssName -class Delegator: - """Base class to support delegation for augmented assignment nodes - To generator code for augmented assignments, we use the following - wrapper classes. In visitAugAssign, the left-hand expression node - is visited twice. The first time the visit uses the normal method - for that node . The second time the visit uses a different method - that generates the appropriate code to perform the assignment. - These delegator classes wrap the original AST nodes in order to - support the variant visit methods. - """ - def __init__(self, obj): - self.obj = obj - def __getattr__(self, attr): - return getattr(self.obj, attr) +class AugLoadVisitor(ast.ASTVisitor): + def __init__(self, main_visitor): + self.main = main_visitor -class AugGetattr(Delegator): - pass - -class AugName(Delegator): - pass + def default(self, node): + raise RuntimeError("shouldn't arrive here!") + + def visitName(self, node ): + self.main.loadName(node.varname) -class AugSlice(Delegator): - pass + def visitGetattr(self, node): + node.expr.accept( self ) + self.main.emit('DUP_TOP') + self.main.emitop('LOAD_ATTR', self.main.mangle(node.attrname)) -class AugSubscript(Delegator): - pass + def visitSlice(self, node): + self.main.visitSlice(node, 1) -wrapper = { - ast.Getattr: AugGetattr, - ast.Name: AugName, - ast.Slice: AugSlice, - ast.Subscript: AugSubscript, - } + def visitSubscript(self, node): + if len(node.subs) > 1: + raise SyntaxError( "augmented assignment to tuple is not possible" ) + self.main.visitSubscript(node, 1) -def wrap_aug(node): - return wrapper[node.__class__](node) +class AugStoreVisitor(ast.ASTVisitor): + def __init__(self, main_visitor): + self.main = main_visitor + + def default(self, node): + raise RuntimeError("shouldn't arrive here!") + + def visitName(self, node): + self.main.storeName(node.varname) -for klass in (ModuleCodeGenerator, ExpressionCodeGenerator, InteractiveCodeGenerator, - FunctionCodeGenerator, GenExprCodeGenerator, ClassCodeGenerator): - klass.NameFinder = LocalNameFinder - klass.FunctionGen = FunctionCodeGenerator - klass.ClassGen = ClassCodeGenerator + def visitGetattr(self, node): + self.main.emit('ROT_TWO') + self.main.emitop('STORE_ATTR', self.main.mangle(node.attrname)) + def visitSlice(self, node): + slice = 0 + if node.lower: + slice = slice | 1 + if node.upper: + slice = slice | 2 + if slice == 0: + self.main.emit('ROT_TWO') + elif slice == 3: + self.main.emit('ROT_FOUR') + else: + self.main.emit('ROT_THREE') + self.main.emit('STORE_SLICE+%d' % slice) + def visitSubscript(self, node): + if len(node.subs) > 1: + raise SyntaxError( "augmented assignment to tuple is not possible" ) + self.main.emit('ROT_THREE') + self.main.emit('STORE_SUBSCR') if __name__ == "__main__": for file in sys.argv[1:]: Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Thu Aug 25 11:25:42 2005 @@ -4,6 +4,7 @@ from pypy.interpreter.astcompiler.consts import SC_LOCAL, SC_GLOBAL, \ SC_FREE, SC_CELL, SC_UNKNOWN, SC_REALLY_GLOBAL from pypy.interpreter.astcompiler.misc import mangle +from pypy.interpreter.pyparser.error import SyntaxError import types @@ -471,6 +472,7 @@ # a yield statement signals a generator def visitYield(self, node ): + scope = self.cur_scope() scope.generator = 1 node.value.accept( self ) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Thu Aug 25 11:25:42 2005 @@ -323,12 +323,15 @@ """ def compile(self, source, filename, mode, flags): from pyparser.error import ParseError - from pyparser.pythonutil import internal_pypy_parse_to_ast + from pyparser.pythonutil import AstBuilder, PYTHON_PARSER, TARGET_DICT flags |= __future__.generators.compiler_flag # always on (2.2 compat) - # XXX use 'flags' space = self.space try: - encoding, ast_tree = internal_pypy_parse_to_ast(source, mode, True, flags) + builder = AstBuilder(space=space) + target_rule = TARGET_DICT[mode] + PYTHON_PARSER.parse_source(source, target_rule, builder, flags) + ast_tree = builder.rule_stack[-1] + encoding = builder.source_encoding except ParseError, e: raise OperationError(space.w_SyntaxError, e.wrap_info(space, filename)) @@ -339,6 +342,7 @@ # __________ # XXX this uses the non-annotatable astcompiler at interp-level from pypy.interpreter import astcompiler + from pyparser.error import SyntaxError from pypy.interpreter.astcompiler.pycodegen import ModuleCodeGenerator from pypy.interpreter.astcompiler.pycodegen import InteractiveCodeGenerator from pypy.interpreter.astcompiler.pycodegen import ExpressionCodeGenerator @@ -347,11 +351,11 @@ astcompiler.misc.set_filename(filename, ast_tree) flag_names = get_flag_names( flags ) if mode == 'exec': - codegenerator = ModuleCodeGenerator(ast_tree, flag_names) + codegenerator = ModuleCodeGenerator(space, ast_tree, flag_names) elif mode == 'single': - codegenerator = InteractiveCodeGenerator(ast_tree, flag_names) + codegenerator = InteractiveCodeGenerator(space, ast_tree, flag_names) else: # mode == 'eval': - codegenerator = ExpressionCodeGenerator(ast_tree, flag_names) + codegenerator = ExpressionCodeGenerator(space, ast_tree, flag_names) c = codegenerator.getCode() except SyntaxError, e: w_synerr = space.newtuple([space.wrap(e.msg), @@ -367,8 +371,8 @@ raise OperationError(space.w_TypeError,space.wrap(str(e))) # __________ end of XXX above from pypy.interpreter.pycode import PyCode - code = PyCode(space)._from_code(c) - return code + assert isinstance(c,PyCode) + return c #compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Thu Aug 25 11:25:42 2005 @@ -265,7 +265,7 @@ return genexpr_fors -def get_docstring(stmt): +def get_docstring(builder,stmt): """parses a Stmt node. If a docstring if found, the Discard node is **removed** @@ -276,15 +276,15 @@ """ if not isinstance(stmt, ast.Stmt): return None - doc = None + doc = builder.wrap_none() if len(stmt.nodes): first_child = stmt.nodes[0] if isinstance(first_child, ast.Discard): expr = first_child.expr - if isinstance(expr, ast.StringConst): + if builder.is_string_const(expr): # This *is* a docstring, remove it from stmt list del stmt.nodes[0] - doc = expr.string_value + doc = expr.value return doc @@ -341,21 +341,6 @@ atoms.reverse() return atoms -def eval_number(value): - """temporary implementation - eval_number intends to replace number = eval(value) ; return number - """ - from pypy.objspace.std.strutil import string_to_int, string_to_float - from pypy.objspace.std.strutil import string_to_long - from pypy.objspace.std.strutil import ParseStringError - if value.endswith('l') or value.endswith('L'): - value = value[:-1] - # ??? - try: - return string_to_int(value) - except ParseStringError: - return string_to_float(value) - def eval_string(value): """temporary implementation @@ -385,6 +370,7 @@ result = result.replace(escaped, value) return result + ## misc utilities, especially for power: rule def reduce_callfunc(obj, arglist): """generic factory for CallFunc nodes""" @@ -495,14 +481,14 @@ elif top.name == tok.NAME: builder.push( ast.Name(top.get_value()) ) elif top.name == tok.NUMBER: - builder.push(ast.NumberConst(eval_number(top.get_value()))) + builder.push(ast.Const(builder.eval_number(top.get_value()))) elif top.name == tok.STRING: # need to concatenate strings in atoms s = '' for token in atoms: assert isinstance(token, TokenObject) s += eval_string(token.get_value()) - builder.push(ast.StringConst(s)) + builder.push(ast.Const(builder.wrap_string(s))) elif top.name == tok.BACKQUOTE: builder.push(ast.Backquote(atoms[1])) else: @@ -707,7 +693,7 @@ for n in range(0,l,2): node = atoms[n] if isinstance(node, TokenObject) and node.name == tok.NEWLINE: - nodes.append(ast.Discard(ast.NoneConst())) + nodes.append(ast.Discard(ast.Const(builder.wrap_none()))) else: nodes.append(node) builder.push(ast.Stmt(nodes)) @@ -717,12 +703,11 @@ if len(atoms) > 2: assert False, "return several stmts not implemented" elif len(atoms) == 1: - builder.push(ast.Return(ast.NoneConst(), None)) # XXX lineno + builder.push(ast.Return(ast.Const(builder.wrap_none()), None)) # XXX lineno else: builder.push(ast.Return(atoms[1], None)) # XXX lineno def build_file_input(builder, nb): - doc = None stmts = [] atoms = get_atoms(builder, nb) for node in atoms: @@ -736,13 +721,20 @@ else: stmts.append(node) main_stmt = ast.Stmt(stmts) - doc = get_docstring(main_stmt) + doc = get_docstring(builder,main_stmt) return builder.push(ast.Module(doc, main_stmt)) +def build_eval_input(builder, nb): + doc = builder.wrap_none() + stmts = [] + atoms = get_atoms(builder, nb) + assert len(atoms)>=1 + return builder.push(ast.Expression(atoms[0])) + def build_single_input( builder, nb ): atoms = get_atoms( builder, nb ) l = len(atoms) - if l >= 1: + if l == 1 or l==2: builder.push(ast.Module(None, atoms[0])) else: assert False, "Forbidden path" @@ -851,7 +843,7 @@ sliceobj_infos = [] for value in sliceinfos: if value is None: - sliceobj_infos.append(ast.NoneConst()) + sliceobj_infos.append(ast.Const(builder.wrap_none())) else: sliceobj_infos.append(value) builder.push(SlicelistObject('sliceobj', sliceobj_infos, None)) @@ -929,7 +921,7 @@ funcname = funcname_token.get_value() arglist = atoms[2] code = atoms[-1] - doc = get_docstring(code) + doc = get_docstring(builder, code) builder.push(ast.Function(decorator_node, funcname, names, default, flags, doc, code)) @@ -953,7 +945,7 @@ basenames.append(node) else: basenames.append(base) - doc = get_docstring(body) + doc = get_docstring(builder,body) builder.push(ast.Class(classname, basenames, doc, body)) def build_suite(builder, nb): @@ -1303,6 +1295,7 @@ sym.try_stmt : build_try_stmt, sym.exprlist : build_exprlist, sym.decorator : build_decorator, + sym.eval_input : build_eval_input, } ## Stack elements definitions ################################### @@ -1447,9 +1440,10 @@ class AstBuilder(BaseGrammarBuilder): """A builder that directly produce the AST""" - def __init__(self, rules=None, debug=0): + def __init__(self, rules=None, debug=0, space=None): BaseGrammarBuilder.__init__(self, rules, debug) self.rule_stack = [] + self.space = space def context(self): return AstBuilderContext(self.rule_stack) @@ -1530,6 +1524,47 @@ self.push_tok(name, value, source) return True + def eval_number(self, value): + """temporary implementation + eval_number intends to replace number = eval(value) ; return number + """ + from pypy.objspace.std.strutil import string_to_int, string_to_float + from pypy.objspace.std.strutil import string_to_w_long, interp_string_to_float + from pypy.objspace.std.strutil import ParseStringError + space = self.space + base = 10 + if value.startswith("0x") or value.startswith("0X"): + base = 16 + elif value.startswith("0"): + base = 8 + if value.endswith('l') or value.endswith('L'): + value = value[:-1] + return string_to_w_long( space, value, base=base ) + try: + value = string_to_int(value, base=base) + return space.wrap(value) + except ParseStringError: + return space.wrap(interp_string_to_float(space,value)) + + def is_string_const(self, expr): + if not isinstance(expr,ast.Const): + return False + space = self.space + return space.is_true(space.isinstance(expr.value,space.w_str)) + + def wrap_string(self, obj): + if self.space: + return self.space.wrap(obj) + else: + return obj + + def wrap_none(self): + if self.space: + return self.space.w_None + else: + return None + + def show_stack(before, after): """debugging helper function""" size1 = len(before) Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Thu Aug 25 11:25:42 2005 @@ -115,6 +115,17 @@ code1 = codegenerator.getCode() return code1 +def target_ast_compile(space, input, mode): + from pypy.interpreter.astcompiler import ast, misc, pycodegen + builder = AstBuilder(rules=None, debug=0, space=space) + target = TARGET_DICT[mode] + PYTHON_PARSER.parse_source(input, target, builder) + ast_tree = builder.rule_stack[-1] + misc.set_filename("", ast_tree) + codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) + code1 = codegenerator.getCode() + return code1 + def internal_pypy_parse_to_ast(source, mode='exec', lineno=False, flags=0): builder = AstBuilder() Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Thu Aug 25 11:25:42 2005 @@ -55,7 +55,9 @@ if not arglist_equal(left_args, right_args): return False elif isinstance(left,stable_ast.Const): - if isinstance(right,ast_ast.NoneConst): + if isinstance(right,ast_ast.Const): + return left.value == right.value + elif isinstance(right,ast_ast.NoneConst): return left.value == None elif isinstance(right, ast_ast.NumberConst): return left.value == right.number_value @@ -159,6 +161,10 @@ "l = (i for j in k for i in j)", "l = (i for j in k for i in j if j%2==0)", "l = (i for j in k if j%2 == 0 if j*2 < 20 for i in j if i%2==0)", + "l = (i for i in [ j*2 for j in range(10) ] )", + "l = [i for i in ( j*2 for j in range(10) ) ]", + "l = (i for i in [ j*2 for j in ( k*3 for k in range(10) ) ] )", + "l = [i for j in ( j*2 for j in [ k*3 for k in range(10) ] ) ]", ] @@ -413,8 +419,63 @@ 'return (a,b,c,d)', ] +augassigns = [ + 'a=1;a+=2', + 'a=1;a-=2', + 'a=1;a*=2', + 'a=1;a/=2', + 'a=1;a//=2', + 'a=1;a%=2', + 'a=1;a**=2', + 'a=1;a>>=2', + 'a=1;a<<=2', + 'a=1;a&=2', + 'a=1;a^=2', + 'a=1;a|=2', + + 'a=A();a.x+=2', + 'a=A();a.x-=2', + 'a=A();a.x*=2', + 'a=A();a.x/=2', + 'a=A();a.x//=2', + 'a=A();a.x%=2', + 'a=A();a.x**=2', + 'a=A();a.x>>=2', + 'a=A();a.x<<=2', + 'a=A();a.x&=2', + 'a=A();a.x^=2', + 'a=A();a.x|=2', + + 'a=A();a[0]+=2', + 'a=A();a[0]-=2', + 'a=A();a[0]*=2', + 'a=A();a[0]/=2', + 'a=A();a[0]//=2', + 'a=A();a[0]%=2', + 'a=A();a[0]**=2', + 'a=A();a[0]>>=2', + 'a=A();a[0]<<=2', + 'a=A();a[0]&=2', + 'a=A();a[0]^=2', + 'a=A();a[0]|=2', + + 'a=A();a[0:2]+=2', + 'a=A();a[0:2]-=2', + 'a=A();a[0:2]*=2', + 'a=A();a[0:2]/=2', + 'a=A();a[0:2]//=2', + 'a=A();a[0:2]%=2', + 'a=A();a[0:2]**=2', + 'a=A();a[0:2]>>=2', + 'a=A();a[0:2]<<=2', + 'a=A();a[0:2]&=2', + 'a=A();a[0:2]^=2', + 'a=A();a[0:2]|=2', + ] + TESTS = [ expressions, + augassigns, comparisons, funccalls, backtrackings, @@ -448,9 +509,27 @@ 'eval' : 'eval_input', } + +class FakeSpace: + w_None = None + w_str = str + w_int = int + + def wrap(self,obj): + return obj + + def isinstance(self, obj, wtype ): + return isinstance(obj,wtype) + + def is_true(self, obj): + return obj + + def newtuple(self, lst): + return tuple(lst) + def ast_parse_expr(expr, target='single'): target = TARGET_DICT[target] - builder = AstBuilder() + builder = AstBuilder(space=FakeSpace()) PYTHON_PARSER.parse_source(expr, target, builder) return builder Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Thu Aug 25 11:25:42 2005 @@ -1,19 +1,20 @@ from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER from pypy.interpreter.pyparser.astbuilder import AstBuilder - - -from pypy.interpreter.pyparser.pythonutil import ast_from_input +from pypy.interpreter.pycode import PyCode import py.test from pypy.interpreter.astcompiler import ast, misc, pycodegen from test_astbuilder import expressions, comparisons, funccalls, backtrackings,\ listmakers, genexps, dictmakers, multiexpr, attraccess, slices, imports,\ - asserts, execs, prints, globs, raises, imports_newstyle + asserts, execs, prints, globs, raises, imports_newstyle, augassigns + +from test_astbuilder import FakeSpace TESTS = [ expressions, + augassigns, comparisons, funccalls, backtrackings, @@ -42,18 +43,18 @@ 'eval' : 'eval_input', } -def ast_parse_expr(expr, target='single'): +def ast_parse_expr(expr, target='single', space=FakeSpace()): target = TARGET_DICT[target] - builder = AstBuilder() + builder = AstBuilder(space=space) PYTHON_PARSER.parse_source(expr, target, builder) return builder.rule_stack[-1] ### Note: builtin compile and compiler.compile behave differently -def compile_expr( expr, target="single" ): +def compile_expr( expr, target="exec" ): return compile( expr, "", target ) -def ast_compile( expr, target="single" ): +def ast_compile( expr, target="exec" ): from compiler import compile return compile( expr, "", target ) @@ -71,15 +72,42 @@ dis.dis(code2) assert code1.co_code == code2.co_code assert code1.co_varnames == code2.co_varnames + + assert len(code1.co_consts) == len(code2.co_consts) + for c1, c2 in zip( code1.co_consts, code2.co_consts ): + if type(c1)==PyCode: + c1 = to_code(c1) + return compare_code( c1, c2 ) + else: + assert c1 == c2 -def check_compile( expr ): +def to_code( rcode ): import new - ast_tree = ast_parse_expr( expr ) + code = new.code( rcode.co_argcount, + rcode.co_nlocals, + rcode.co_stacksize, + rcode.co_flags, + rcode.co_code, + rcode.co_consts_w, + tuple(rcode.co_names), + tuple(rcode.co_varnames), + rcode.co_filename, + rcode.co_name, + rcode.co_firstlineno, + rcode.co_lnotab, + tuple(rcode.co_freevars), + tuple(rcode.co_cellvars) ) + return code + +def check_compile( expr ): + space = FakeSpace() + ast_tree = ast_parse_expr( expr, target='exec', space=space ) misc.set_filename("", ast_tree) print "Compiling:", expr - #print ast_tree - codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) - code1 = new.code(*codegenerator.getCode()) + print ast_tree + codegenerator = pycodegen.ModuleCodeGenerator(space,ast_tree) + rcode = codegenerator.getCode() + code1 = to_code( rcode ) code2 = ast_compile( expr ) compare_code(code1,code2) Modified: pypy/dist/pypy/translator/goal/targetcompiler.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetcompiler.py (original) +++ pypy/dist/pypy/translator/goal/targetcompiler.py Thu Aug 25 11:25:42 2005 @@ -12,11 +12,26 @@ # __________ Entry point __________ # entry_point = annotateme -from pypy.interpreter.pyparser.pythonutil import ast_compile -entry_point = ast_compile +from pypy.interpreter.pyparser.pythonutil import target_ast_compile +from pypy.objspace.std.objspace import StdObjSpace + +def entry_point( s1, s2 ): + global space + return target_ast_compile( space, s1, s2 ) # _____ Define and setup target ___ def target(): + global space, w_entry_point + # disable translation of the whole of classobjinterp.py + StdObjSpace.setup_old_style_classes = lambda self: None + # disable geninterp for now -- we have faaar toooo much interp-level code + # for the poor translator already + # XXX why can't I enable this? crashes the annotator! + space = StdObjSpace(nofaking=True, + compiler="astparser", + translating=True, + #usemodules=['marhsal', '_sre'], + geninterp=False) return entry_point, [str, str] # _____ Run translated _____ From hpk at codespeak.net Thu Aug 25 11:55:59 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 11:55:59 +0200 (CEST) Subject: [pypy-svn] r16452 - in pypy/dist/pypy/interpreter: . stablecompiler test Message-ID: <20050825095559.DB27027B60@code1.codespeak.net> Author: hpk Date: Thu Aug 25 11:55:58 2005 New Revision: 16452 Modified: pypy/dist/pypy/interpreter/pycode.py pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/stablecompiler/pyassem.py pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/test/test_exec.py Log: (hpk,arigo,samuele) more closely mirror the code object's flags from CPython regarding the locals dict on frames. Makes another (added) scope-related test pass that previously failed. Modified: pypy/dist/pypy/interpreter/pycode.py ============================================================================== --- pypy/dist/pypy/interpreter/pycode.py (original) +++ pypy/dist/pypy/interpreter/pycode.py Thu Aug 25 11:55:58 2005 @@ -248,11 +248,20 @@ else: return None - def dictscope_needed(self): + def initialize_frame_scopes(self, frame): # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS. # class bodies only have CO_NEWLOCALS. - return not (self.co_flags & CO_OPTIMIZED) - + # CO_NEWLOCALS: make a locals dict unless optimized is also set + # CO_OPTIMIZED: no locals dict needed at all + flags = self.co_flags + if flags & CO_OPTIMIZED: + return + if flags & CO_NEWLOCALS: + frame.w_locals = frame.space.newdict([]) + else: + assert frame.w_globals is not None + frame.w_locals = frame.w_globals + def getjoinpoints(self): """Compute the bytecode positions that are potential join points (for FlowObjSpace)""" Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Thu Aug 25 11:55:58 2005 @@ -46,9 +46,7 @@ self.builtin = space.builtin.pick_builtin(w_globals) # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS. # class bodies only have CO_NEWLOCALS. - if code.dictscope_needed(): - self.w_locals = space.newdict([]) # set to None by Frame.__init__ - + code.initialize_frame_scopes(self) self.fastlocals_w = [None]*self.numlocals self.w_f_trace = None self.last_instr = -1 Modified: pypy/dist/pypy/interpreter/stablecompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pyassem.py Thu Aug 25 11:55:58 2005 @@ -317,7 +317,8 @@ class PyFlowGraph(FlowGraph): super_init = FlowGraph.__init__ - def __init__(self, name, filename, args=(), optimized=0, klass=None): + def __init__(self, name, filename, args=(), optimized=0, + klass=None, newlocals=0): self.super_init() self.name = name self.filename = filename @@ -325,10 +326,11 @@ self.args = args # XXX self.argcount = getArgCount(args) self.klass = klass + self.flags = 0 if optimized: - self.flags = CO_OPTIMIZED | CO_NEWLOCALS - else: - self.flags = 0 + self.flags |= CO_OPTIMIZED + if newlocals: + self.flags |= CO_NEWLOCALS self.consts = [] self.names = [] # Free variables found by the symbol table scan, including Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Thu Aug 25 11:55:58 2005 @@ -1290,7 +1290,8 @@ args, hasTupleArg = generateArgList(func.argnames) self.graph = pyassem.PyFlowGraph(name, func.filename, args, - optimized=1) + optimized=self.localsfullyknown, + newlocals=1) self.isLambda = isLambda self.super_init() Modified: pypy/dist/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exec.py (original) +++ pypy/dist/pypy/interpreter/test/test_exec.py Thu Aug 25 11:55:58 2005 @@ -159,3 +159,13 @@ import sys assert d['platform'] == 3 + def test_exec_load_name(self): + d = {'x': 2} + exec """if 1: + def f(): + save = x + exec "x=3" + return x,save + """ in d + res = d['f']() + assert res == (3, 2) From cfbolz at codespeak.net Thu Aug 25 12:05:38 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 12:05:38 +0200 (CEST) Subject: [pypy-svn] r16453 - pypy/dist/pypy/doc Message-ID: <20050825100538.556F627B4B@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 12:05:37 2005 New Revision: 16453 Modified: pypy/dist/pypy/doc/news.txt Log: added some more info to the heidelberg news item. Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Thu Aug 25 12:05:37 2005 @@ -12,18 +12,17 @@ Ongoing: PyPy Sprint in Heidelberg 22nd-29th August 2005 ========================================================== -The current PyPy sprint takes place at the Heidelberg University +The current `PyPy sprint`_ takes place at the Heidelberg University in Germany from 22nd August to 29th August (both days included). Its main focus is translation of the whole PyPy interpreter to a low level language and reaching 2.4.1 Python compliancy. The goal of the sprint is to release a first self-contained -PyPy-0.7 version. To learn more see the `Heidelberg sprint -announcement`_ or look at the list of people_ that are -expected to come. - -.. _people: http://codespeak.net/pypy/extradoc/sprintinfo/heidelberg-people.html -.. _`Heidelberg sprint announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/Heidelberg-sprint.html +PyPy-0.7 version. Carl has written a report about `day 1 - 3`_ +and there are also some pictures_ online. +.. _`PyPy sprint`: http://codespeak.net/pypy/extradoc/sprintinfo/Heidelberg-sprint.html +.. _`day 1 - 3`: http://codespeak.net/pipermail/pypy-dev/2005q3/002287.html +.. _pictures: http://codespeak.net/~hpk/heidelberg-sprint/ PyPy Hildesheim2 finished: first self-contained PyPy run! =========================================================== From ale at codespeak.net Thu Aug 25 12:08:16 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 12:08:16 +0200 (CEST) Subject: [pypy-svn] r16454 - pypy/dist/pypy/interpreter Message-ID: <20050825100816.D21A627B6A@code1.codespeak.net> Author: ale Date: Thu Aug 25 12:08:15 2005 New Revision: 16454 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: (ludovic, arre, ale) Don't convert UnicodeError into ValueError. Give an error messages explaining that the original exception was before changed into ValueError. Fixes the last failing test of test_unicode.py Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Thu Aug 25 12:08:15 2005 @@ -231,8 +231,16 @@ space.wrap(e.offset), space.wrap(e.text)])]) raise OperationError(space.w_SyntaxError, w_synerr) + except UnicodeDecodeError, e: + raise OperationError(space.w_UnicodeDecodeError, space.newtuple([ + space.wrap(e.encoding), space.wrap(e.object), space.wrap(e.start), + space.wrap(e.end), space.wrap(e.reason)])) except ValueError,e: - raise OperationError(space.w_ValueError,space.wrap(str(e))) + if e.__class__ != ValueError: + extra_msg = "(Really go %s)" % e.__class__.__name__ + else: + extra_msg = "" + raise OperationError(space.w_ValueError,space.wrap(str(e)+extra_msg)) except TypeError,e: raise OperationError(space.w_TypeError,space.wrap(str(e))) # __________ end of XXX above From rxe at codespeak.net Thu Aug 25 12:21:32 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 12:21:32 +0200 (CEST) Subject: [pypy-svn] r16455 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825102132.4D9BD27B5B@code1.codespeak.net> Author: rxe Date: Thu Aug 25 12:21:31 2005 New Revision: 16455 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: Refactor out a bit the gereration process and extract only the code we are interested in. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 12:21:31 2005 @@ -23,13 +23,41 @@ from pypy.translator.translator import Translator +from py.process import cmdexec function_count = {} -def get_ll(ccode): +def get_ll(ccode, functions=[]): + # goto codespeak and compile our c code request = urllib.urlencode({'ccode':ccode}) - return urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() + llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() + # get rid of the struct that llvm-gcc introduces to struct types + llcode = llcode.replace("%struct.", "%") + + # create file + extern_dir = udir.join("externs").mkdir() + llfilename = extern_dir.join("externs").new(ext='.ll') + f = open(str(llfilename), 'w') + f.write(llcode) + f.close() + + # create bytecode + os.chdir(str(extern_dir)) + cmdexec('llvm-as externs.ll') + bcfilename = extern_dir.join("externs").new(ext='.bc') + if functions: + for func in functions: + # extract + cmdexec('llvm-extract -func %s -o %s.bc externs.bc' % (func, func)) + + # link all the ll files + functions_bcs = ' '.join(['%s.bc' % func for func in functions]) + cmdexec('llvm-link -o externs_linked.bc ' + functions_bcs) + bcfilename = extern_dir.join("externs_linked").new(ext='.bc') + + return bcfilename + class GenLLVM(object): def __init__(self, translator, debug=True): @@ -102,12 +130,7 @@ j = os.path.join p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") - genllcode += open(p).read() - print genllcode - - ll_str = get_ll(genllcode) - ll_str = ll_str.replace("%struct.", "%") - return ll_str + return get_ll(open(p).read(), ['ll_math_frexp', 'll_math_is_error']) def replace_with_machine_words(self, s): return s.replace('UINT',self.db.get_machine_uword()).replace('INT',self.db.get_machine_word()) @@ -135,8 +158,7 @@ self.translator.rtyper.specialize_more_blocks() self.db.setup_all() - print self.generate_llfile(extern_decls) - #XXXXassert False + self.generate_llfile(extern_decls) #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) From cfbolz at codespeak.net Thu Aug 25 12:44:37 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 12:44:37 +0200 (CEST) Subject: [pypy-svn] r16458 - pypy/dist/pypy/doc Message-ID: <20050825104437.831DF27B49@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 12:44:35 2005 New Revision: 16458 Modified: pypy/dist/pypy/doc/architecture.txt pypy/dist/pypy/doc/coding-guide.txt pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/interpreter.txt pypy/dist/pypy/doc/objspace.txt pypy/dist/pypy/doc/theory.txt pypy/dist/pypy/doc/translation.txt Log: Tried to consistently use the term "bytecode interpreter" in our whole documentation. Modified: pypy/dist/pypy/doc/architecture.txt ============================================================================== --- pypy/dist/pypy/doc/architecture.txt (original) +++ pypy/dist/pypy/doc/architecture.txt Thu Aug 25 12:44:35 2005 @@ -92,7 +92,7 @@ The *standard interpreter* is the subsystem implementing the Python language. It is divided in two components: -- the `plain interpreter`_ which is responsible for interpreting +- the `bytecode interpreter`_ which is responsible for interpreting code objects and implementing bytecodes, - the `standard object space`_ which implements creation, access and @@ -102,12 +102,14 @@ (the C Implementation of Python led by Guido van Rossum), if one is willing to pay for the double-interpretation performance penalty. +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Please note that we are using the term *interpreter* most often in reference to the *plain interpreter* which just knows enough to read, dispatch and implement *bytecodes* thus shuffling objects around on the stack and between namespaces. The (plain) interpreter is completely ignorant of how to access, modify or construct objects and their structure and thus delegates such operations to a so called `Object Space`_. +XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX In addition, the standard interpreter requires a parser and bytecode compiler to turn the user's Python source code into a form amenable to @@ -123,7 +125,7 @@ is done in four steps: - producing a *flow graph* representation of the standard interpreter. - A combination of a `plain interpreter`_ and a *flow object space* + A combination of a `bytecode interpreter`_ and a *flow object space* performs *abstract interpretation* to record the flow of objects and execution throughout a python program into such a *flow graph*. @@ -138,7 +140,7 @@ See below for the `translation process in more details`_. -.. _`plain interpreter`: +.. _`bytecode interpreter`: The Bytecode Interpreter ========================= @@ -179,7 +181,7 @@ All object-space operations take and return `application-level`_ objects. There are only a few, very simple, object-space operation which allows the -interpreter to gain some knowledge about the value of an +bytecode interpreter to gain some knowledge about the value of an application-level object. The most important one is ``is_true()``, which returns a boolean interpreter-level value. This is necessary to implement, for example, @@ -187,13 +189,13 @@ conditional-branching bytecodes into which if-statements get compiled). We currently have four working object spaces which can be plugged into -the interpreter: +the bytecode interpreter: .. _`standard object space`: - The *Standard Object Space* is a complete implementation of the various built-in types and objects of Python. The Standard Object - Space, together with the interpreter, is the foundation of our Python + Space, together with the bytecode interpreter, is the foundation of our Python implementation. Internally, it is a set of `interpreter-level`_ classes implementing the various `application-level`_ objects -- integers, strings, lists, types, etc. To draw a comparison with CPython, the Standard Object @@ -210,9 +212,9 @@ globally replaces an object with another. - the *Flow Object Space* transforms a Python program into a - flow-graph representation, by recording all operations that the interpreter - would like to perform when it is shown the given Python program. This - technique is explained `later in this document`_. + flow-graph representation, by recording all operations that the bytecode + interpreter would like to perform when it is shown the given Python + program. This technique is explained `later in this document`_. For a description of the object spaces, please see the `objspace document`_. The sources of PyPy contain the various object spaces @@ -348,8 +350,8 @@ ============================================== One of PyPy's now-short-term objectives is to enable translation of our -interpreter and standard object space into a lower-level language. In -order for our translation and type inference mechanisms to work +bytecode interpreter and standard object space into a lower-level language. +In order for our translation and type inference mechanisms to work effectively, we need to restrict the dynamism of our interpreter-level Python code at some point. However, in the start-up phase, we are completely free to use all kind of nice python constructs, including @@ -359,7 +361,7 @@ adhere to a more static subset of Python: Restricted Python, also known as `RPython`_. -The Flow Object Space then, with the help of our plain interpreter, +The Flow Object Space then, with the help of our bytecode interpreter, works through those initialized RPython code objects. The result of this `abstract interpretation`_ is a flow graph: yet another representation of a python program, but one which is suitable for Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Thu Aug 25 12:44:35 2005 @@ -363,7 +363,7 @@ Operations on ``w_xxx`` ----------------------- -The core interpreter considers wrapped objects as black boxes. +The core bytecode interpreter considers wrapped objects as black boxes. It is not allowed to inspect them directly. The allowed operations are all implemented on the object space: they are called ``space.xxx()``, where ``xxx`` is a standard operation @@ -387,13 +387,13 @@ Building ``w_xxx`` objects -------------------------- -From the core interpreter, wrapped objects are usually built as the result of +From the bytecode interpreter, wrapped objects are usually built as the result of an object space operation. The ways to directly create a wrapped object are: * ``space.wrap(x)``: returns a wrapped object containing the value ``x``. Only works if ``x`` is either a simple value (integer, float, string) or an instance of an internal - interpreter class (Function, Code, Frame...). + bytecode interpreter class (Function, Code, Frame...). * ``space.newlist([w_x, w_y, w_z...])``: returns a wrapped list from a list of already-wrapped objects. @@ -424,7 +424,7 @@ Inspecting and unwrapping ``w_xxx`` objects -------------------------------------------- -The most delicate operation is for the interpreter to inspect +The most delicate operation is for the bytecode interpreter to inspect a wrapped object, which must be done via the object space. * ``space.is_true(w_x)``: checks if the given wrapped object Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Thu Aug 25 12:44:35 2005 @@ -421,12 +421,12 @@ relative to the PyPy toplevel directory). You may look at our `directory reference`_ or start off at one of the following points: -* `pypy/interpreter`_ contains the basic interpreter: bytecode dispatcher +* `pypy/interpreter`_ contains the bytecode interpreter: bytecode dispatcher in pyopcode.py_, frame and code objects in eval.py_ and pyframe.py_, function objects and argument passing in function.py_ and argument.py_, the object space interface definition in baseobjspace.py_, modules in - module.py_ and mixedmodule.py_. Core types supporting the interpreter are - defined in typedef.py_. + module.py_ and mixedmodule.py_. Core types supporting the bytecode + interpreter are defined in typedef.py_. * `pypy/objspace/std`_ contains the `Standard object space`_. The main file is objspace.py_. For each type, the files ``xxxtype.py`` and @@ -435,7 +435,8 @@ * `pypy/objspace`_ contains a few other object spaces: the thunk_ one, the trace_ one, the flow_ one. The latter is a relatively short piece - of code that builds the control flow graphs when the interpreter runs in it. + of code that builds the control flow graphs when the bytecode interpreter + runs in it. * `pypy/translator`_ contains the code analysis and generation stuff. Start reading from translator.py_, from which it should be easy to follow Modified: pypy/dist/pypy/doc/interpreter.txt ============================================================================== --- pypy/dist/pypy/doc/interpreter.txt (original) +++ pypy/dist/pypy/doc/interpreter.txt Thu Aug 25 12:44:35 2005 @@ -55,7 +55,7 @@ transparent invocation of application-level helpers (``app2interp``) at interpreter-level. -Another task of the interpreter is to expose its basic +Another task of the bytecode interpreter is to expose its basic code, frame, module and function objects to application-level code. Such runtime introspection and modification abilities are implemented via `interpreter descriptors`_ (also see Raymond Hettingers @@ -84,8 +84,8 @@ .. _`application level exceptions`: coding-guide.html#applevel-exceptions -Interpreter Implementation Classes -====================================== +Bytecode Interpreter Implementation Classes +=========================================== .. _`Frame class`: @@ -357,7 +357,7 @@ ------------------------------ Python traditionally has a very far-reaching introspection model -for interpreter related objects. In PyPy and in CPython read +for bytecode interpreter related objects. In PyPy and in CPython read and write accesses to such objects are routed to descriptors. Of course, in CPython those are implemented in ``C`` while in PyPy they are implemented in interpreter-level Python code. Modified: pypy/dist/pypy/doc/objspace.txt ============================================================================== --- pypy/dist/pypy/doc/objspace.txt (original) +++ pypy/dist/pypy/doc/objspace.txt Thu Aug 25 12:44:35 2005 @@ -73,7 +73,11 @@ --------------------------------------- **wrap(x):** - Returns a wrapped object that is a reference to the interpreter-level object x. This can be used either on simple immutable objects (integers, strings...) to create a new wrapped object, or on complex mutable objects to obtain an application-level-visible reference to them (e.g. instances of internal interpreter classes). + Returns a wrapped object that is a reference to the interpreter-level object + x. This can be used either on simple immutable objects (integers, + strings...) to create a new wrapped object, or on complex mutable objects to + obtain an application-level-visible reference to them (e.g. instances of + internal bytecode interpreter classes). **newbool(b):** Creates a Bool Object from an interpreter level object. @@ -103,7 +107,8 @@ Return Interpreter Level equivalent of w_x **interpclass_w(w_x):** - If w_x is a wrapped instance of an interpreter class -- for example Function, Frame, Cell, etc. -- return it unwrapped. Otherwise return None. + If w_x is a wrapped instance of an bytecode interpreter class -- for example + Function, Frame, Cell, etc. -- return it unwrapped. Otherwise return None. **int_w(w_x):** If w_x is an application-level integer or long which can be converted without overflow to an integer, return an interpreter-level integer. Otherwise raise TypeError or OverflowError. @@ -158,7 +163,17 @@ The Standard Object Space (StdObjSpace_) is the direct equivalent of CPython's object library (the "Objects/" subdirectory in the distribution). It is an implementation of the common Python types in a lower-level language. -The Standard Object Space defines an abstract parent class, W_Object, and a bunch of subclasses like W_IntObject, W_ListObject, and so on. A wrapped object (a "black box" for the interpreter main loop) is thus an instance of one of these classes. When the main loop invokes an operation, say the addition, between two wrapped objects w1 and w2, the Standard Object Space does some internal dispatching (similar to "Object/abstract.c" in CPython) and invokes a method of the proper W_XyzObject class that can do the operation. The operation itself is done with the primitives allowed by RestrictedPython. The result is constructed as a wrapped object again. For example, compare the following implementation of integer addition with the function "int_add()" in "Object/intobject.c": :: +The Standard Object Space defines an abstract parent class, W_Object, and a +bunch of subclasses like W_IntObject, W_ListObject, and so on. A wrapped +object (a "black box" for the bytecode interpreter main loop) is thus an +instance of one of these classes. When the main loop invokes an operation, say +the addition, between two wrapped objects w1 and w2, the Standard Object Space +does some internal dispatching (similar to "Object/abstract.c" in CPython) and +invokes a method of the proper W_XyzObject class that can do the +operation. The operation itself is done with the primitives allowed by +RestrictedPython. The result is constructed as a wrapped object again. For +example, compare the following implementation of integer addition with the +function "int_add()" in "Object/intobject.c": :: def add__Int_Int(space, w_int1, w_int2): x = w_int1.intval @@ -282,9 +297,10 @@ The task of the FlowObjSpace_ is to generate a control-flow graph from a function. This graph will also contain a trace of the individual operations, so that it is actually just an alternate representation for the function. -The FlowObjSpace is an object space, which means that it exports the standard object space interface and it is driven by the interpreter. +The FlowObjSpace is an object space, which means that it exports the standard +object space interface and it is driven by the bytecode interpreter. -The basic idea is that if the interpreter is given a function, e.g.:: +The basic idea is that if the bytecode interpreter is given a function, e.g.:: def f(n): return 3*n+2 @@ -293,7 +309,10 @@ .. _`Abstract Interpretation`: theory.html#abstract-interpretation -For example, if the placeholder ``v1`` is given as the argument to the above function, the interpreter will call ``v2 = space.mul(space.wrap(3), v1)`` and then ``v3 = space.add(v2, space.wrap(2))`` and return ``v3`` as the result. During these calls the FlowObjSpace will record a basic block:: +For example, if the placeholder ``v1`` is given as the argument to the above +function, the bytecode interpreter will call ``v2 = space.mul(space.wrap(3), +v1)`` and then ``v3 = space.add(v2, space.wrap(2))`` and return ``v3`` as the +result. During these calls the FlowObjSpace will record a basic block:: Block(v1): # input argument v2 = mul(Constant(3), v1) @@ -378,11 +397,27 @@ How the FlowObjSpace works -------------------------- -The FlowObjSpace works by recording all operations issued by the interpreter into basic blocks. A basic block ends in one of two cases: when the interpreters calls ``is_true()``, or when a joinpoint is reached. - -* A joinpoint occurs when the next operation is about to be recorded into the current block, but there is already another block that records an operation for the same bytecode position. This means that the interpreter has closed a loop and is interpreting already-seen code again. In this situation, we interrupt the interpreter and we make a link from the end of the current block back to the previous block, thus closing the loop in the flow graph as well. (Note that this occurs only when an operation is about to be recorded, which allows some amount of constant-folding.) - -* If the interpreter calls ``is_true()``, the FlowObjSpace doesn't generally know if the answer should be True or False, so it puts a conditional jump and generates two successor blocks for the current basic block. There is some trickery involved so that the interpreter is fooled into thinking that ``is_true()`` first returns False (and the subsequent operations are recorded in the first successor block), and later the *same* call to ``is_true()`` also returns True (and the subsequent operations go this time to the other successor block). +The FlowObjSpace works by recording all operations issued by the bytecode +interpreter into basic blocks. A basic block ends in one of two cases: when +the bytecode interpreters calls ``is_true()``, or when a joinpoint is reached. + +* A joinpoint occurs when the next operation is about to be recorded into the + current block, but there is already another block that records an operation + for the same bytecode position. This means that the bytecode interpreter + has closed a loop and is interpreting already-seen code again. In this + situation, we interrupt the bytecode interpreter and we make a link from the + end of the current block back to the previous block, thus closing the loop + in the flow graph as well. (Note that this occurs only when an operation is + about to be recorded, which allows some amount of constant-folding.) + +* If the bytecode interpreter calls ``is_true()``, the FlowObjSpace doesn't + generally know if the answer should be True or False, so it puts a + conditional jump and generates two successor blocks for the current basic + block. There is some trickery involved so that the bytecode interpreter is + fooled into thinking that ``is_true()`` first returns False (and the + subsequent operations are recorded in the first successor block), and later + the *same* call to ``is_true()`` also returns True (and the subsequent + operations go this time to the other successor block). (This section to be extended...) Modified: pypy/dist/pypy/doc/theory.txt ============================================================================== --- pypy/dist/pypy/doc/theory.txt (original) +++ pypy/dist/pypy/doc/theory.txt Thu Aug 25 12:44:35 2005 @@ -10,11 +10,21 @@ Abstract Interpretation ======================= -Abstract Interpretation is a general technique which consists of an interpreter that follows the bytecode instructions of a user program, just like a normal interpreter does, but with abstract objects instead of concrete ones. Remember that in PyPy this is done by using alternate object spaces with the same interpreter main loop. +Abstract Interpretation is a general technique which consists of an +interpreter that follows the bytecode instructions of a user program, just +like a normal interpreter does, but with abstract objects instead of concrete +ones. Remember that in PyPy this is done by using alternate object spaces with +the same bytecode interpreter main loop. As a theoretical example, the most abstract object space would be the one manipulating the most abstract objects that you could imagine: they are all equivalent, because we have abstracted away any information about the object. There is actually only one of them left, and we could call it "the object". In Python terms, an AbstractObjectSpace could use None for all its wrapped objects. Any operation between wrapped objects gives None again as the wrapped result -- there is nothing else it could give anyway. So when you have said that the add method of AbstractObjectSpace takes None and None and returns None you have said everything. -The point of such an object space is for example to check the bytecode. The interpreter will really run your bytecode, just with completely abstract arguments. If there is no problem then you are sure that the bytecode is valid. You could also record, during this abstract interpretation, how much the stack ever grows; that would give you a fool-proof method of computing or checking the co_stacksize argument of a code object. (There are subtleties which I won't describe here, but that's the basic idea.) +The point of such an object space is for example to check the bytecode. The +bytecode interpreter will really run your bytecode, just with completely +abstract arguments. If there is no problem then you are sure that the bytecode +is valid. You could also record, during this abstract interpretation, how much +the stack ever grows; that would give you a fool-proof method of computing or +checking the co_stacksize argument of a code object. (There are subtleties +which I won't describe here, but that's the basic idea.) Typically, however, abstract object spaces are a (little) bit less abstract, still maintaining a minimal amount of information about the objects. For example, a wrapped object could be represented by its type. You then define the object space's add to return int when the two arguments are int and int. That way, you abstractedly call a function with the input argument's types and what the interpreter will do is a type inference. (Here also there are subtle problems, even besides the remark that integer operations can overflow and actually return longs in a real Python implementation.) Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Thu Aug 25 12:44:35 2005 @@ -992,11 +992,11 @@ Solution -------- -This bootstrap issue is solved by invoking a new interpreter which +This bootstrap issue is solved by invoking a new bytecode interpreter which runs on FlowObjspace. FlowObjspace is complete without complicated initialization. It is able to do abstract interpretation of any Rpythonic code, without actually implementing anything. It just -records all the operations the interpreter would have done by +records all the operations the bytecode interpreter would have done by building flowgraphs for all the code. What the Python backend does is just to produce correct Python code from these flowgraphs and return it as source code. @@ -1023,8 +1023,9 @@ ... ... """) -This call has invoked a PyPy interpreter running on FlowObjspace, recorded every -possible codepath into a flowgraph, and then rendered the following source code:: +This call has invoked a PyPy bytecode interpreter running on FlowObjspace, +recorded every possible codepath into a flowgraph, and then rendered the +following source code:: >>> print source #!/bin/env python From arigo at codespeak.net Thu Aug 25 12:46:13 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 12:46:13 +0200 (CEST) Subject: [pypy-svn] r16459 - pypy/dist/pypy/module/thread Message-ID: <20050825104613.8711127B49@code1.codespeak.net> Author: arigo Date: Thu Aug 25 12:46:07 2005 New Revision: 16459 Modified: pypy/dist/pypy/module/thread/gil.py pypy/dist/pypy/module/thread/os_local.py pypy/dist/pypy/module/thread/threadlocals.py Log: For now, use string-keyed instead of integer-keyed dictionaries in module/thread, in an effort to make it translatable. Modified: pypy/dist/pypy/module/thread/gil.py ============================================================================== --- pypy/dist/pypy/module/thread/gil.py (original) +++ pypy/dist/pypy/module/thread/gil.py Thu Aug 25 12:46:07 2005 @@ -15,6 +15,7 @@ """A version of OSThreadLocals that enforces a GIL.""" def __init__(self): + OSThreadLocals.__init__(self) self.GIL = thread.allocate_lock() def enter_thread(self, space): Modified: pypy/dist/pypy/module/thread/os_local.py ============================================================================== --- pypy/dist/pypy/module/thread/os_local.py (original) +++ pypy/dist/pypy/module/thread/os_local.py Thu Aug 25 12:46:07 2005 @@ -17,16 +17,18 @@ self.space = space self.initargs = initargs ident = thread.get_ident() - self.dicts = {ident: space.newdict([])} + # XXX use string-keyed dicts only for now + self.dicts = {str(ident): space.newdict([])} def getdict(self): ident = thread.get_ident() + key = str(ident) try: - w_dict = self.dicts[ident] + w_dict = self.dicts[key] except KeyError: # create a new dict for this thread space = self.space - w_dict = self.dicts[ident] = space.newdict([]) + w_dict = self.dicts[key] = space.newdict([]) # call __init__ try: w_self = space.wrap(self) @@ -35,7 +37,7 @@ space.call_args(w_init, self.initargs.prepend(w_self)) except: # failed, forget w_dict and propagate the exception - del self.dicts[ident] + del self.dicts[key] raise # ready space.threadlocals.atthreadexit(space, finish_thread, self) @@ -47,7 +49,7 @@ space.wrap("setting dictionary to a non-dict")) self.getdict() # force a dict to exist first ident = thread.get_ident() - self.dicts[ident] = w_dict + self.dicts[str(ident)] = w_dict def descr_local__new__(space, w_subtype, __args__): # XXX check __args__ @@ -70,4 +72,4 @@ def finish_thread(w_obj): assert isinstance(w_obj, Local) ident = thread.get_ident() - del w_obj.dicts[ident] + del w_obj.dicts[str(ident)] Modified: pypy/dist/pypy/module/thread/threadlocals.py ============================================================================== --- pypy/dist/pypy/module/thread/threadlocals.py (original) +++ pypy/dist/pypy/module/thread/threadlocals.py Thu Aug 25 12:46:07 2005 @@ -10,15 +10,17 @@ a thread finishes. This works as long as the thread was started by os_thread.bootstrap().""" - _valuedict = {} # {thread_ident: ExecutionContext()} + def __init__(self): + # XXX use string-keyed dicts only for now + self._valuedict = {} # {str(thread_ident): ExecutionContext()} def getvalue(self): ident = thread.get_ident() - return self._valuedict.get(ident, None) + return self._valuedict.get(str(ident), None) def setvalue(self, value): ident = thread.get_ident() - self._valuedict[ident] = value + self._valuedict[str(ident)] = value def enter_thread(self, space): "Notification that the current thread is just starting." @@ -35,7 +37,7 @@ finally: ident = thread.get_ident() try: - del self._valuedict[ident] + del self._valuedict[str(ident)] except KeyError: pass From hpk at codespeak.net Thu Aug 25 12:46:57 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 12:46:57 +0200 (CEST) Subject: [pypy-svn] r16460 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20050825104657.9E17727B53@code1.codespeak.net> Author: hpk Date: Thu Aug 25 12:46:56 2005 New Revision: 16460 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Log: fix to the python compiler: raise SyntaxError instead of issueing DELETE_DEREF Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Thu Aug 25 12:46:56 2005 @@ -269,6 +269,10 @@ self._nameOp('LOAD', name) def delName(self, name): + scope = self.scope.check_name(name) + if scope == SC_CELL: + raise SyntaxError("can not delete variable '%s' " + "referenced in nested scope" % name) self._nameOp('DELETE', name) def _nameOp(self, prefix, name): From ludal at codespeak.net Thu Aug 25 12:51:04 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 12:51:04 +0200 (CEST) Subject: [pypy-svn] r16462 - in pypy/dist/pypy: interpreter/pyparser interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050825105104.3D5CC27B48@code1.codespeak.net> Author: ludal Date: Thu Aug 25 12:51:02 2005 New Revision: 16462 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/lib/_stablecompiler/transformer.py Log: - fix test_syntax by setting appropriate error message in case of delete f() - updated stablecompiler, _stablecompiler and added TODO to astcompiler Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Thu Aug 25 12:51:02 2005 @@ -318,7 +318,9 @@ ast_node.flags = flags return ast_node else: - assert False, "TODO" + # TODO: check type of ast_node and raise according SyntaxError in case + # of del f() + raise SyntaxError("cannot assign to %s" % ast_node ) def is_augassign( ast_node ): if ( isinstance( ast_node, ast.Name ) or Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Thu Aug 25 12:51:02 2005 @@ -929,6 +929,7 @@ l = self.com_node(node) if l.__class__ in (Name, Slice, Subscript, Getattr): return l + print node # XXX raise SyntaxError, "can't assign to %s" % l.__class__.__name__ def com_assign(self, node, assigning): @@ -1001,7 +1002,10 @@ if t == token.LSQB: return self.com_subscriptlist(primary, node[2], assigning) if t == token.LPAR: - raise SyntaxError, "can't assign to function call" + if assigning==OP_DELETE: + raise SyntaxError, "can't delete function call" + else: + raise SyntaxError, "can't assign to function call" raise SyntaxError, "unknown trailer type: %s" % t def com_assign_attr(self, primary, node, assigning): Modified: pypy/dist/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/transformer.py Thu Aug 25 12:51:02 2005 @@ -997,7 +997,10 @@ if t == token.LSQB: return self.com_subscriptlist(primary, node[2], assigning) if t == token.LPAR: - raise SyntaxError, "can't assign to function call" + if assigning==OP_DELETE: + raise SyntaxError, "can't delete function call" + else: + raise SyntaxError, "can't assign to function call" raise SyntaxError, "unknown trailer type: %s" % t def com_assign_attr(self, primary, node, assigning): From cfbolz at codespeak.net Thu Aug 25 12:56:38 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 12:56:38 +0200 (CEST) Subject: [pypy-svn] r16464 - pypy/dist/pypy/doc Message-ID: <20050825105638.B2F0C27B48@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 12:56:37 2005 New Revision: 16464 Modified: pypy/dist/pypy/doc/architecture.txt Log: ooops, remove section that is no longer needed now that we hopefully use "bytecode interpreter" everywhere. Modified: pypy/dist/pypy/doc/architecture.txt ============================================================================== --- pypy/dist/pypy/doc/architecture.txt (original) +++ pypy/dist/pypy/doc/architecture.txt Thu Aug 25 12:56:37 2005 @@ -102,15 +102,6 @@ (the C Implementation of Python led by Guido van Rossum), if one is willing to pay for the double-interpretation performance penalty. -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -Please note that we are using the term *interpreter* most often in -reference to the *plain interpreter* which just knows enough to read, -dispatch and implement *bytecodes* thus shuffling objects around on the -stack and between namespaces. The (plain) interpreter is completely -ignorant of how to access, modify or construct objects and their -structure and thus delegates such operations to a so called `Object Space`_. -XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - In addition, the standard interpreter requires a parser and bytecode compiler to turn the user's Python source code into a form amenable to interpretation. This is currently still borrowed from CPython, but we From cfbolz at codespeak.net Thu Aug 25 12:57:18 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 12:57:18 +0200 (CEST) Subject: [pypy-svn] r16465 - pypy/dist/pypy/doc Message-ID: <20050825105718.34D1327B48@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 12:57:17 2005 New Revision: 16465 Modified: pypy/dist/pypy/doc/coding-guide.txt Log: add description of the new feature to pass in values into AppTests Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Thu Aug 25 12:57:17 2005 @@ -891,6 +891,22 @@ runs at application level. If you need to use modules you have to import them within the test function. +Another possibility to pass in data into the AppTest is to use +the ``setup_class`` method of the AppTest. All wrapped objects that are +attached to the class there and start with ``w_`` can be accessed +via self (but without the ``w_``) in the actual test method. An example:: + + from pypy.objspace.std import StdObjSpace + + class AppTestErrno: + def setup_class(cls): + cls.space = StdObjSpace() + cls.w_d = cls.space.wrap({"a": 1, "b", 2}) + + def test_dict(self): + assert self.d["a"] == 1 + assert self.d["b"] == 2 + .. _`run the tests as usual`: Command line tool test_all From ludal at codespeak.net Thu Aug 25 13:07:13 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 13:07:13 +0200 (CEST) Subject: [pypy-svn] r16466 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050825110713.87A6027B47@code1.codespeak.net> Author: ludal Date: Thu Aug 25 13:07:11 2005 New Revision: 16466 Added: pypy/dist/lib-python/modified-2.4.1/test/test_parser.py - copied, changed from r16456, pypy/dist/lib-python/2.4.1/test/test_parser.py Log: - removed IllegalSyntaxTestCase since it's testing grammatically incorrect parse tree (which cannot ever be produced by the parser) represented as tuples fed back to the parser internal. it makes no sense to verify this functionnality of the parser module since our parse trees are internally represented as tuples From ericvrp at codespeak.net Thu Aug 25 13:08:36 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 13:08:36 +0200 (CEST) Subject: [pypy-svn] r16468 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825110836.62E0627B47@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 13:08:35 2005 New Revision: 16468 Modified: pypy/dist/pypy/translator/llvm2/varsize.py Log: always clear malloc data until we have a 'bugfree' standalone Modified: pypy/dist/pypy/translator/llvm2/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/varsize.py (original) +++ pypy/dist/pypy/translator/llvm2/varsize.py Thu Aug 25 13:08:35 2005 @@ -26,9 +26,10 @@ codewriter.malloc("%ptr", "sbyte", "%usize", atomic=atomicmalloc) codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") - if ARRAY is STR.chars: - #XXX instead of memset we could probably just zero the hash and string terminator - codewriter.call('%memset_result', 'sbyte*', '%memset', ['%ptr', '0', '%usize',], ['sbyte*', word, uword], cconv='ccc') + #if ARRAY is STR.chars: + # #XXX instead of memset we could probably just zero the hash and string terminator + # codewriter.call('%memset_result', 'sbyte*', '%memset', ['%ptr', '0', '%usize',], ['sbyte*', word, uword], cconv='ccc') + codewriter.call('%memset_result', 'sbyte*', '%memset', ['%ptr', '0', '%usize',], ['sbyte*', word, uword], cconv='ccc') indices_to_arraylength = tuple(indices_to_array) + (("uint", 0),) # the following accesses the length field of the array From ericvrp at codespeak.net Thu Aug 25 13:09:42 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 13:09:42 +0200 (CEST) Subject: [pypy-svn] r16469 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825110942.6197E27B47@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 13:09:41 2005 New Revision: 16469 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: patch c->llvm external function .ll file to contain correct calling convertion Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 13:09:41 2005 @@ -35,6 +35,42 @@ # get rid of the struct that llvm-gcc introduces to struct types llcode = llcode.replace("%struct.", "%") + #find function names, declare them internal with fastcc calling convertion + ll_lines = [] + funcnames = { + "%ll_frexp_result__Float_Signed" : True, + "%prepare_and_raise_ZeroDivisionError" : True, + "%prepare_and_raise_OverflowError" : True, + "%prepare_and_raise_ValueError" : True, + } + for line in llcode.split('\n'): + comment = line.find(';') + if comment >= 0: + line = line[:comment] + line = line.rstrip() + if line[-1:] == '{': + returntype, s = line.split(' ', 1) + funcname , s = s.split('(', 1) + funcnames[funcname] = True + line = 'internal fastcc ' + line + ll_lines.append(line) + + #patch calls to function that we just declared fastcc + ll_lines2 = [] + for line in ll_lines: + calltag = 'call ' + i = line.find(calltag) + if i >= 0: + cconv = 'ccc' + for funcname in funcnames.keys(): + if line.find(funcname) >= 0: + cconv = 'fastcc' + break + line = "%scall %s %s" % (line[:i], cconv, line[i+len(calltag):]) + ll_lines2.append(line) + + llcode = '\n'.join(ll_lines2) + # create file extern_dir = udir.join("externs").mkdir() llfilename = extern_dir.join("externs").new(ext='.ll') From cfbolz at codespeak.net Thu Aug 25 13:30:12 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 13:30:12 +0200 (CEST) Subject: [pypy-svn] r16472 - pypy/dist/pypy/doc Message-ID: <20050825113012.BAB0927B47@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 13:30:11 2005 New Revision: 16472 Modified: pypy/dist/pypy/doc/faq.txt pypy/dist/pypy/doc/index.txt Log: update the faq and add a link to it Modified: pypy/dist/pypy/doc/faq.txt ============================================================================== --- pypy/dist/pypy/doc/faq.txt (original) +++ pypy/dist/pypy/doc/faq.txt Thu Aug 25 13:30:11 2005 @@ -4,9 +4,17 @@ How fast is PyPy? - As of June 2005, PyPy still runs on top of CPython and thus - is slower by a factor of 2000 compared to CPython. We don't - know yet how fast it will be once we complete our translation - efforts, aimed at a first static self-contained low-level - translated version. + As of August 2005, PyPy was succesfully translated to C. + The version of PyPy that still runs on top of CPython + is slower by a factor of 2000 compared to CPython. The translated + versions seems to be roughly 300 times slower than CPython. + On the other hand, the really interesting question is: Why is + PyPy so slow? + + Why is PyPy so slow? + + Our translation process does not optimize the produced code very + much yet. Just one example: if you use a ``for i in range(x)`` loop + the loop will be ended by raising an exception (although the ``range`` + list will not be created in its entirety). \ No newline at end of file Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Thu Aug 25 13:30:11 2005 @@ -23,6 +23,9 @@ `parser`_ contains the beginnings of documentation about the parser (and the compiler at some point). +`FAQ`_ contains the beginning of frequently asked questions. +Right now it's a bit empty. + `talks and related projects`_ lists presentations and related projects. From rxe at codespeak.net Thu Aug 25 13:34:19 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 13:34:19 +0200 (CEST) Subject: [pypy-svn] r16474 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050825113419.23C8B27B47@code1.codespeak.net> Author: rxe Date: Thu Aug 25 13:34:17 2005 New Revision: 16474 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py Log: ericvrp/rxe Fix in failing tests to sync up. * Some refactoring and cleaning up build_llvm_module.py Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Thu Aug 25 13:34:17 2005 @@ -14,129 +14,7 @@ from pypy.translator.llvm2.log import log EXCEPTIONS_SWITCHES = "-enable-correct-eh-support" -#--regalloc iterativescan" #unstable (http://llvm.cs.uiuc.edu/docs/ReleaseNotes.html) - -OPTIMIZATION_SWITCHES = (" ".join([ - - # call %malloc -> malloc inst - "-raiseallocs", - - # clean up disgusting code - "-simplifycfg", - - # kill useless allocas - "-mem2reg", - - # optimize out global vars - "-globalopt", - - # remove unused fns and globs - "-globaldce", - - # interprocedural constant propagation - "-ipconstprop", - - # dead argument elimination - "-deadargelim", - - # clean up after - # (interprocedural constant propagation) & (dead argument elimination) - "-instcombine ", "-simplifycfg ", - - # clean up after - # (interprocedural constant propagation) & (dead argument elimination) - "-instcombine ", "-simplifycfg ", - - # remove dead EH info - "-prune-eh", - - # inline small functions - "-inline", - - # simplify well-known library calls - "-simplify-libcalls", - - # promote 'by reference' arguments to scalars - "-argpromotion", - - # recover type information - "--raise", - - # simplify cfg by copying code - "-tailduplicate", - - # merge & remove bacic blocks - "--simplifycfg", - - # break up aggregate allocas - "-scalarrepl", - - # combine silly seq's - "-instcombine", - - # propagate conditionals - "-condprop", - - # eliminate tail calls - '-tailcallelim', - - # merge & remove BBs - "-simplifycfg", - - # reassociate expressions - "-reassociate", - - # hoist loop invariants (LICM - Loop Invariant Code Motion) - "-licm", - - # clean up after LICM/reassoc - "-instcombine", - - # canonicalize indvars - "-indvars", - - # unroll small loops - "-loop-unroll", - - # clean up after the unroller - "-instcombine", - - # GVN for load instructions - "-load-vn", - - # remove common subexprs (Global Common Subexpression Elimination) - "-gcse", - - # constant prop with SCCP (Sparse Conditional Constant Propagation) - "-sccp", - - - # Run instcombine after redundancy elimination to exploit opportunities - # opened up by them - "-instcombine", - - # propagate conditionals - "-condprop", - - # Delete dead stores - "-dse", - - # SSA based 'Aggressive DCE' - "-adce", - - # merge & remove BBs - "-simplifycfg", - - # eliminate dead types - "-deadtypeelim", - - # merge dup global constants - "-constmerge", - ])) - - -# XXX Tmp for debugging -OPTIMIZATION_SWITCHES = (" ".join([ +SIMPLE_OPTIMIZATION_SWITCHES = (" ".join([ # call %malloc -> malloc inst "-raiseallocs", @@ -151,7 +29,6 @@ "-simplifycfg", ])) - # suggested by: gccas /dev/null -o /dev/null -debug-pass=Arguments OPTIMIZATION_SWITCHES = (" ".join([ "-verify -lowersetjmp -funcresolve -raiseallocs -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -raise -tailduplicate -simplifycfg -scalarrepl -instcombine -break-crit-edges -condprop -tailcallelim -simplifycfg -reassociate -loopsimplify -licm -instcombine -indvars -loop-unroll -instcombine -load-vn -gcse -sccp -instcombine -break-crit-edges -condprop -dse -mergereturn -adce -simplifycfg -deadtypeelim -constmerge -verify" @@ -193,11 +70,18 @@ gc_libs = '' if optimize: - cmds = ["llvm-as < %s.ll | opt %s > %s.bc" % (b, OPTIMIZATION_SWITCHES, b)] + optimization_switches = OPTIMIZATION_SWITCHES else: - cmds = ["llvm-as < %s.ll > %s.bc" % (b, b)] + optimization_switches = SIMPLE_OPTIMIZATION_SWITCHES + + cmds = ["llvm-as %s.ll" % b] - if sys.maxint == 2147483647: #32 bit platform + bcfile = dirpath.join("externs", "externs_linked.bc") + cmds.append("llvm-link %s.bc %s -o %s_all.bc" % (b, str(bcfile), b)) + ball = str(dirpath.join('%s_all.bc' % b)) + cmds.append("opt %s %s -f -o %s.bc" % (OPTIMIZATION_SWITCHES, ball, b)) + + if False and sys.maxint == 2147483647: #32 bit platform cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) if exe_name: @@ -219,7 +103,7 @@ try: try: for cmd in cmds: - log.build(cmd) + #log.build(cmd) cmdexec(cmd) if pyxfile: make_c_from_pyxfile(pyxfile) @@ -249,14 +133,3 @@ return testmodule if exe_name: return exe_name - -if __name__ == "__main__": - - # TMP - Conveinence during debugging - b = "entry_point" - print "opt %s -f %s.bc -o %s_optimized.bc" % (OPTIMIZATION_SWITCHES, b, b) - print "llc %s %s_optimized.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b) - print "as %s.s -o %s.o" % (b, b) - gc_libs = '-lgc -lpthread' - exe_name = "pypy" - print "gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 13:34:17 2005 @@ -27,7 +27,8 @@ function_count = {} -def get_ll(ccode, functions=[]): +def get_ll(ccode, extern_dir, functions=[]): + # goto codespeak and compile our c code request = urllib.urlencode({'ccode':ccode}) llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() @@ -72,7 +73,6 @@ llcode = '\n'.join(ll_lines2) # create file - extern_dir = udir.join("externs").mkdir() llfilename = extern_dir.join("externs").new(ext='.ll') f = open(str(llfilename), 'w') f.write(llcode) @@ -142,7 +142,11 @@ return decls def generate_llfile(self, extern_decls): - # hack to get file + + extern_dir = udir.join("externs") + if extern_dir.check(dir=1): + return + extern_dir.mkdir() genllcode = "" @@ -166,7 +170,7 @@ j = os.path.join p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") - return get_ll(open(p).read(), ['ll_math_frexp', 'll_math_is_error']) + return get_ll(open(p).read(), extern_dir, ['ll_math_frexp', 'll_math_is_error']) def replace_with_machine_words(self, s): return s.replace('UINT',self.db.get_machine_uword()).replace('INT',self.db.get_machine_word()) Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 13:34:17 2005 @@ -5,11 +5,17 @@ #define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW +// c forward declarations +double frexp(double, int*); + struct RPyFREXP_RESULT; +struct RPyMODF_RESULT; + struct RPyFREXP_RESULT *ll_frexp_result__Float_Signed(double, int); +struct RPyMODF_RESULT *ll_frexp_result__Float_Float(double, double); -void prepare_and_raise_ValueError(char *); void prepare_and_raise_OverflowError(char *); +void prepare_and_raise_ValueError(char *); int ll_math_is_error(double x) { if (errno == ERANGE) { @@ -31,6 +37,184 @@ } while(0) +double ll_math_pow(double x, double y) { + double r; + LL_MATH_ERROR_RESET; + r = pow(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_atan2(double x, double y) { + double r; + LL_MATH_ERROR_RESET; + r = atan2(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_fmod(double x, double y) { + double r; + LL_MATH_ERROR_RESET; + r = fmod(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_ldexp(double x, long y) { + double r; + LL_MATH_ERROR_RESET; + r = ldexp(x, (int) y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_hypot(double x, double y) { + double r; + LL_MATH_ERROR_RESET; + r = hypot(x, y); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +struct RPyMODF_RESULT* ll_math_modf(double x) { + double intpart, fracpart; + LL_MATH_ERROR_RESET; + fracpart = modf(x, &intpart); + LL_MATH_CHECK_ERROR(fracpart, NULL); + return ll_modf_result(fracpart, intpart); +} + +/* simple math function */ + +double ll_math_acos(double x) { + double r; + LL_MATH_ERROR_RESET; + r = acos(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_asin(double x) { + double r; + LL_MATH_ERROR_RESET; + r = asin(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_atan(double x) { + double r; + LL_MATH_ERROR_RESET; + r = atan(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_ceil(double x) { + double r; + LL_MATH_ERROR_RESET; + r = ceil(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_cos(double x) { + double r; + LL_MATH_ERROR_RESET; + r = cos(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_cosh(double x) { + double r; + LL_MATH_ERROR_RESET; + r = cosh(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_exp(double x) { + double r; + LL_MATH_ERROR_RESET; + r = exp(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_fabs(double x) { + double r; + LL_MATH_ERROR_RESET; + r = fabs(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_floor(double x) { + double r; + LL_MATH_ERROR_RESET; + r = floor(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_log(double x) { + double r; + LL_MATH_ERROR_RESET; + r = log(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_log10(double x) { + double r; + LL_MATH_ERROR_RESET; + r = log10(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_sin(double x) { + double r; + LL_MATH_ERROR_RESET; + r = sin(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_sinh(double x) { + double r; + LL_MATH_ERROR_RESET; + r = sinh(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_sqrt(double x) { + double r; + LL_MATH_ERROR_RESET; + r = sqrt(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_tan(double x) { + double r; + LL_MATH_ERROR_RESET; + r = tan(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + +double ll_math_tanh(double x) { + double r; + LL_MATH_ERROR_RESET; + r = tanh(x); + LL_MATH_CHECK_ERROR(r, -1.0); + return r; +} + struct RPyFREXP_RESULT* ll_math_frexp(double x) { int expo; double m; Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Thu Aug 25 13:34:17 2005 @@ -47,13 +47,6 @@ for function in functions: extfunctions["%ll_math_" + function] = ((), simple_function_template % locals()) -#extfunctions["%ll_math_frexp"] = (("%__debug",), """ -#internal fastcc %RPyFREXP_RESULT* %ll_math_frexp(double %x) { -# call fastcc void %__debug([12 x sbyte]* %__ll_math_frexp) ; XXX: TODO: ll_math_frexp -# ret %RPyFREXP_RESULT* null -#} -#""") - extfunctions["%ll_math_hypot"] = (("%__debug",), """ internal fastcc double %ll_math_hypot(double %x, double %y) { call fastcc void %__debug([12 x sbyte]* %__ll_math_hypot) ; XXX: TODO: ll_math_hypot @@ -86,117 +79,6 @@ extfunctions["%ll_math_frexp"] = (("%prepare_and_raise_OverflowError", "%prepare_and_raise_ValueError"), """ -declare int* %__errno_location() - -internal fastcc int %ll_math_is_error(double %x) { -entry: - %x_addr = alloca double ; ty=double* - %result = alloca int ; ty=int* - store double %x, double* %x_addr - %tmp.0 = call int* ()* %__errno_location() ; ty=int* - %tmp.1 = load int* %tmp.0 ; ty=int - %tmp.2 = seteq int %tmp.1, 34 ; ty=bool - %tmp.3 = cast bool %tmp.2 to int ; ty=int - br bool %tmp.2, label %then.0, label %else -then.0: - %tmp.4 = load double* %x_addr ; ty=double - %tmp.5 = seteq double %tmp.4, 0x0000000000000000 ; ty=bool - %tmp.6 = cast bool %tmp.5 to int ; ty=int - br bool %tmp.5, label %then.1, label %endif.1 -then.1: - store int 0, int* %result - br label %return -after_ret.0: - br label %endif.1 -endif.1: - call fastcc void (sbyte*)* %prepare_and_raise_OverflowError(sbyte* getelementptr ([17 x sbyte]* %.str_1, int 0, int 0)) - br label %endif.0 -else: - call fastcc void (sbyte*)* %prepare_and_raise_ValueError(sbyte* getelementptr ([18 x sbyte]* %.str_2, int 0, int 0)) - br label %endif.0 -endif.0: - store int 1, int* %result - br label %return -after_ret.1: - br label %return -return: - %tmp.9 = load int* %result ; ty=int - ret int %tmp.9 -} - -internal fastcc %RPyFREXP_RESULT* %ll_math_frexp(double %x) { -entry: - %x_addr = alloca double ; ty=double* - %result = alloca %RPyFREXP_RESULT* ; ty=%RPyFREXP_RESULT** - %expo = alloca int ; ty=int* - %m = alloca double ; ty=double* - store double %x, double* %x_addr - %tmp.0 = call int* ()* %__errno_location() ; ty=int* - store int 0, int* %tmp.0 - %tmp.2 = load double* %x_addr ; ty=double - %tmp.1 = call double (double, int*)* %frexp(double %tmp.2, int* %expo) ; ty=double - store double %tmp.1, double* %m - %tmp.3 = call int* ()* %__errno_location() ; ty=int* - %tmp.4 = load int* %tmp.3 ; ty=int - %tmp.5 = seteq int %tmp.4, 0 ; ty=bool - %tmp.6 = cast bool %tmp.5 to int ; ty=int - br bool %tmp.5, label %shortcirc_next.0, label %shortcirc_done.0 -shortcirc_next.0: - %tmp.7 = load double* %m ; ty=double - %tmp.8 = setgt double %tmp.7, 0x7FEFFFFFFFFFFFFF ; ty=bool - %tmp.9 = cast bool %tmp.8 to int ; ty=int - br bool %tmp.8, label %shortcirc_done.1, label %shortcirc_next.1 -shortcirc_next.1: - %tmp.10 = load double* %m ; ty=double - %tmp.11 = setlt double %tmp.10, 0xFFEFFFFFFFFFFFFF ; ty=bool - %tmp.12 = cast bool %tmp.11 to int ; ty=int - br label %shortcirc_done.1 -shortcirc_done.1: - %shortcirc_val.0 = phi bool [ true, %shortcirc_next.0 ], [ %tmp.11, %shortcirc_next.1 ] ; ty=bool - %tmp.13 = cast bool %shortcirc_val.0 to int ; ty=int - br label %shortcirc_done.0 -shortcirc_done.0: - %shortcirc_val.1 = phi bool [ false, %entry ], [ %shortcirc_val.0, %shortcirc_done.1 ] ; ty=bool - %tmp.14 = cast bool %shortcirc_val.1 to int ; ty=int - br bool %shortcirc_val.1, label %then.0, label %endif.0 -then.0: - %tmp.15 = call int* ()* %__errno_location() ; ty=int* - store int 34, int* %tmp.15 - br label %endif.0 -endif.0: - %tmp.16 = call int* ()* %__errno_location() ; ty=int* - %tmp.17 = load int* %tmp.16 ; ty=int - %tmp.18 = setne int %tmp.17, 0 ; ty=bool - %tmp.19 = cast bool %tmp.18 to int ; ty=int - br bool %tmp.18, label %shortcirc_next.2, label %shortcirc_done.2 -shortcirc_next.2: - %tmp.21 = load double* %m ; ty=double - %tmp.20 = call fastcc int (double)* %ll_math_is_error(double %tmp.21) ; ty=int - %tmp.22 = setne int %tmp.20, 0 ; ty=bool - %tmp.23 = cast bool %tmp.22 to int ; ty=int - br label %shortcirc_done.2 -shortcirc_done.2: - %shortcirc_val.2 = phi bool [ false, %endif.0 ], [ %tmp.22, %shortcirc_next.2 ] ; ty=bool - %tmp.24 = cast bool %shortcirc_val.2 to int ; ty=int - br bool %shortcirc_val.2, label %then.1, label %endif.1 -then.1: - store %RPyFREXP_RESULT* null, %RPyFREXP_RESULT** %result - br label %return -after_ret.0: - br label %endif.1 -endif.1: - %tmp.26 = load double* %m ; ty=double - %tmp.27 = load int* %expo ; ty=int - %tmp.25 = call fastcc %RPyFREXP_RESULT* (double, int)* %ll_frexp_result__Float_Signed(double %tmp.26, int %tmp.27) ; ty=%RPyFREXP_RESULT* - store %RPyFREXP_RESULT* %tmp.25, %RPyFREXP_RESULT** %result - br label %return -after_ret.1: - br label %return -return: - %tmp.28 = load %RPyFREXP_RESULT** %result ; ty=%RPyFREXP_RESULT* - ret %RPyFREXP_RESULT* %tmp.28 -} - """) Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Thu Aug 25 13:34:17 2005 @@ -5,7 +5,7 @@ %struct.timezone = type { INT, INT } %typedef.fd_set = type { [32 x INT] } -%.str_1 = internal constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] +%.str_xxx1 = internal constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] declare ccc double %floor(double) declare ccc double %fmod(double, double) @@ -75,7 +75,7 @@ br bool %tmp.12, label %then.1, label %return then.1: ; preds = %entry - ; XXX disabled for now: call void %RaiseSimpleException( INT 1, sbyte* getelementptr ([16 x sbyte]* %.str_1, INT 0, INT 0) ) + ; XXX disabled for now: call void %RaiseSimpleException( INT 1, sbyte* getelementptr ([16 x sbyte]* %.str_xxx1, INT 0, INT 0) ) ret void return: ; preds = %entry Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 13:34:17 2005 @@ -5,12 +5,9 @@ declare ccc INT %strlen(sbyte*) declare ccc INT %strcmp(sbyte*, sbyte*) declare ccc sbyte* %memset(sbyte*, INT, UINT) -declare ccc double %frexp(double, int*) %__print_debug_info = internal global bool false %__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" -%.str_1 = internal constant [17 x sbyte] c"math range error\\00" -%.str_2 = internal constant [18 x sbyte] c"math domain error\\00" """ From cfbolz at codespeak.net Thu Aug 25 13:47:13 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 13:47:13 +0200 (CEST) Subject: [pypy-svn] r16475 - pypy/dist/pypy/rpython/memory Message-ID: <20050825114713.3624A27B4B@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 13:47:12 2005 New Revision: 16475 Modified: pypy/dist/pypy/rpython/memory/lladdress.py Log: fixed tests on 64 bit machines. this is not entirely perfect since I would like to put all the usage of struct into lltypelayout. On the other hand this is difficult becauseof circular imports (they can't be done locally because it's about globals) Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Thu Aug 25 13:47:12 2005 @@ -61,14 +61,14 @@ self.convert_to(value)) class _signed_accessor(_accessor): - format = "i" - size = struct.calcsize("i") + format = "l" + size = struct.calcsize("l") convert_from = int convert_to = int class _unsigned_accessor(_accessor): - format = "I" - size = struct.calcsize("I") + format = "L" + size = struct.calcsize("L") convert_from = r_uint convert_to = long From arigo at codespeak.net Thu Aug 25 13:55:26 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 13:55:26 +0200 (CEST) Subject: [pypy-svn] r16476 - in pypy/dist/pypy/interpreter: stablecompiler test Message-ID: <20050825115526.037CA27B49@code1.codespeak.net> Author: arigo Date: Thu Aug 25 13:55:24 2005 New Revision: 16476 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/test/test_generator.py Log: Test generator expressions in test_generator. Fix for compiling generator expressions. Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Thu Aug 25 13:55:24 2005 @@ -1368,6 +1368,7 @@ def __init__(self, gexp, scopes, class_name, mod): self.scopes = scopes self.scope = scopes[gexp] + self.localsfullyknown = self.scope.localsfullyknown self.__super_init(gexp, scopes, 1, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) Modified: pypy/dist/pypy/interpreter/test/test_generator.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_generator.py (original) +++ pypy/dist/pypy/interpreter/test/test_generator.py Thu Aug 25 13:55:24 2005 @@ -47,3 +47,10 @@ yield i me = g() raises(ValueError, me.next) + + def test_generator_expression(self): + import sys + if sys.version_info < (2, 4): + skip("generator expressions only work on Python >= 2.4") + exec "res = sum(i*i for i in range(5))" + assert res == 30 From ericvrp at codespeak.net Thu Aug 25 13:57:56 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 13:57:56 +0200 (CEST) Subject: [pypy-svn] r16477 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825115756.9B11927B51@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 13:57:56 2005 New Revision: 16477 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: fixed cconv for declares Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 13:57:56 2005 @@ -57,9 +57,8 @@ ll_lines.append(line) #patch calls to function that we just declared fastcc - ll_lines2 = [] + ll_lines2, calltag, declaretag = [], 'call ', 'declare ' for line in ll_lines: - calltag = 'call ' i = line.find(calltag) if i >= 0: cconv = 'ccc' @@ -68,6 +67,13 @@ cconv = 'fastcc' break line = "%scall %s %s" % (line[:i], cconv, line[i+len(calltag):]) + if line[:len(declaretag)] == declaretag: + cconv = 'ccc' + for funcname in funcnames.keys(): + if line.find(funcname) >= 0: + cconv = 'fastcc' + break + line = "declare %s %s" % (cconv, line[len(declaretag):]) ll_lines2.append(line) llcode = '\n'.join(ll_lines2) From nik at codespeak.net Thu Aug 25 14:00:41 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 14:00:41 +0200 (CEST) Subject: [pypy-svn] r16479 - pypy/dist/pypy/module/_sre Message-ID: <20050825120041.0376827B4E@code1.codespeak.net> Author: nik Date: Thu Aug 25 14:00:39 2005 New Revision: 16479 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved MatchContext class from app to interp-level Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Thu Aug 25 14:00:39 2005 @@ -19,6 +19,8 @@ interpleveldefs = { 'getlower': 'interp_sre.getlower', '_State': 'interp_sre.make_state', + '_MatchContext': 'interp_sre.make_context', + '_RepeatContext': 'interp_sre.make_repeat_context', '_check_charset': 'interp_sre.check_charset', '_at_dispatch': 'interp_sre.at_dispatch', '_category_dispatch': 'interp_sre.category_dispatch', Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 14:00:39 2005 @@ -291,52 +291,6 @@ raise TypeError, "cannot copy this pattern object" -class _MatchContext(object): - - def __init__(self, state, pattern_codes): - self.state = state - self.pattern_codes = pattern_codes - self.string_position = state.string_position - self.code_position = 0 - self.has_matched = None - - def push_new_context(self, pattern_offset): - """Creates a new child context of this context and pushes it on the - stack. pattern_offset is the offset off the current code position to - start interpreting from.""" - child_context = _MatchContext(self.state, - self.pattern_codes[self.code_position + pattern_offset:]) - self.state.context_stack.append(child_context) - return child_context - - def peek_char(self, peek=0): - return self.state.string[self.string_position + peek] - - def skip_char(self, skip_count): - self.string_position += skip_count - - def remaining_chars(self): - return self.state.end - self.string_position - - def peek_code(self, peek=0): - return self.pattern_codes[self.code_position + peek] - - def skip_code(self, skip_count): - self.code_position += skip_count - - def remaining_codes(self): - return len(self.pattern_codes) - self.code_position - - def at_beginning(self): - return self.string_position == 0 - - def at_end(self): - return self.string_position == self.state.end - - def at_linebreak(self): - return not self.at_end() and self.peek_char() == "\n" - - def search(state, pattern_codes): flags = 0 if pattern_codes[0] == OPCODES["info"]: @@ -426,7 +380,7 @@ return False dispatcher = _OpcodeDispatcher() - state.context_stack.append(_MatchContext(state, pattern_codes)) + state.context_stack.append(_sre._MatchContext(state, pattern_codes)) has_matched = None while len(state.context_stack) > 0: context = state.context_stack[-1] @@ -436,16 +390,6 @@ return has_matched -class _RepeatContext(_MatchContext): - - def __init__(self, context): - _MatchContext.__init__(self, context.state, - context.pattern_codes[context.code_position:]) - self.count = -1 - self.previous = context.state.repeat - self.last_position = None - - class _Dispatcher(object): DISPATCH_TABLE = None @@ -781,7 +725,7 @@ # operator (MAX_UNTIL, MIN_UNTIL) # <1=min> <2=max> item tail #self._log(ctx, "REPEAT", ctx.peek_code(2), ctx.peek_code(3)) - repeat = _RepeatContext(ctx) + repeat = _sre._RepeatContext(ctx) ctx.state.repeat = repeat ctx.state.string_position = ctx.string_position child_context = ctx.push_new_context(ctx.peek_code(1) + 1) Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 14:00:39 2005 @@ -110,15 +110,21 @@ def fget(space, obj): return space.wrap(getattr(obj, name)) def fset(space, obj, w_value): - return setattr(obj, name, space.int_w(w_value)) + setattr(obj, name, space.int_w(w_value)) return GetSetProperty(fget, fset, cls=cls) +def interp_attrproperty_list_w(name, cls): + "NOT_RPYTHON: initialization-time only" + def fget(space, obj): + return space.newlist(getattr(obj, name)) + return GetSetProperty(fget, cls=cls) + def interp_attrproperty_obj_w(name, cls): "NOT_RPYTHON: initialization-time only" def fget(space, obj): return getattr(obj, name) def fset(space, obj, w_value): - return setattr(obj, name, w_value) + setattr(obj, name, w_value) return GetSetProperty(fget, fset, cls=cls) W_State.typedef = TypeDef("W_State", @@ -141,6 +147,111 @@ lower = interp2app(W_State.lower), ) +def make_context(space, w_state, w_pattern_codes): + # XXX Uhm, temporary + return space.wrap(W_MatchContext(space, w_state, w_pattern_codes)) + +class W_MatchContext(Wrappable): + + def __init__(self, space, w_state, w_pattern_codes): + self.space = space + self.w_state = w_state + self.pattern_codes_w = space.unpackiterable(w_pattern_codes) + self.w_string_position = space.wrap(w_state.string_position) + self.w_code_position = space.wrap(0) + self.w_has_matched = space.w_None + + # XXX These attributes are only really used with repeat operations. + # Formerly a subclass of MatchContext was used for these, but for + # simplictiy we simply add them here for now. + #self.count = space.wrap(-1) + #self.previous = context.state.repeat + #self.last_position = None + + def push_new_context(self, w_pattern_offset): + """Creates a new child context of this context and pushes it on the + stack. pattern_offset is the offset off the current code position to + start interpreting from.""" + pattern_offset = self.space.int_w(w_pattern_offset) + pattern_codes_w = self.pattern_codes_w[ + self.space.int_w(self.w_code_position) + pattern_offset:] + w_child_context = self.space.wrap(W_MatchContext(self.space, self.w_state, + self.space.newlist(pattern_codes_w))) + self.space.call_method(self.w_state.w_context_stack, "append", w_child_context) + #context_stack = self.space.unpackiterable(self.w_state.w_context_stack) + #context_stack.append(w_child_context) + return w_child_context + + def peek_char(self, w_peek=0): + return self.space.getitem(self.w_state.w_string, + self.space.add(self.w_string_position, w_peek)) + + def skip_char(self, w_skip_count): + self.w_string_position = self.space.add(self.w_string_position, w_skip_count) + + def remaining_chars(self): + return self.space.sub(self.space.wrap(self.w_state.end), self.w_string_position) + + def peek_code(self, w_peek=0): + space = self.space + return self.pattern_codes_w[ + space.int_w(space.add(self.w_code_position, w_peek))] + + def skip_code(self, w_skip_count): + self.w_code_position = self.space.add(self.w_code_position, w_skip_count) + + def remaining_codes(self): + return self.space.sub(self.space.wrap(len(self.pattern_codes_w)), + self.w_code_position) + + def at_beginning(self): + return self.space.eq(self.w_string_position, self.space.wrap(0)) + + def at_end(self): + return self.space.eq(self.w_string_position, self.space.wrap(self.w_state.end)) + + def at_linebreak(self): + space = self.space + return space.and_(space.newbool(not space.is_true(self.at_end())), + space.eq(self.peek_char(space.wrap(0)), space.wrap("\n"))) + +W_MatchContext.typedef = TypeDef("W_MatchContext", + state = interp_attrproperty_w("w_state", W_MatchContext), + string_position = interp_attrproperty_obj_w("w_string_position", W_MatchContext), + pattern_codes = interp_attrproperty_list_w("pattern_codes_w", W_MatchContext), + code_position = interp_attrproperty_obj_w("w_code_position", W_MatchContext), + has_matched = interp_attrproperty_obj_w("w_has_matched", W_MatchContext), + push_new_context = interp2app(W_MatchContext.push_new_context), + peek_char = interp2app(W_MatchContext.peek_char), + skip_char = interp2app(W_MatchContext.skip_char), + remaining_chars = interp2app(W_MatchContext.remaining_chars), + peek_code = interp2app(W_MatchContext.peek_code), + skip_code = interp2app(W_MatchContext.skip_code), + remaining_codes = interp2app(W_MatchContext.remaining_codes), + at_beginning = interp2app(W_MatchContext.at_beginning), + at_end = interp2app(W_MatchContext.at_end), + at_linebreak = interp2app(W_MatchContext.at_linebreak), +) + +def make_repeat_context(space, w_context): + # XXX Uhm, temporary + return space.wrap(W_RepeatContext(space, w_context)) + +class W_RepeatContext(W_MatchContext): + + def __init__(self, space, w_context): + W_MatchContext.__init__(self, space, w_context.w_state, + space.newlist(w_context.pattern_codes_w[space.int_w(w_context.w_code_position):])) + self.w_count = space.wrap(-1) + self.w_previous = w_context.w_state.w_repeat + self.w_last_position = space.w_None + +W_RepeatContext.typedef = TypeDef("W_RepeatContext", W_MatchContext.typedef, + count = interp_attrproperty_obj_w("w_count", W_RepeatContext), + previous = interp_attrproperty_obj_w("w_previous", W_RepeatContext), + last_position = interp_attrproperty_obj_w("w_last_position", W_RepeatContext), +) + #### Category helpers ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, From ludal at codespeak.net Thu Aug 25 14:14:38 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 14:14:38 +0200 (CEST) Subject: [pypy-svn] r16480 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050825121438.298AD27B51@code1.codespeak.net> Author: ludal Date: Thu Aug 25 14:14:36 2005 New Revision: 16480 Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py pypy/dist/pypy/interpreter/pyparser/pytokenize.py Log: change error message in an attempt pass test_eof (not yet) Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Thu Aug 25 14:14:36 2005 @@ -123,7 +123,7 @@ if contstr: # continued string if not line: - raise TokenError("EOF in multi-line string", line, + raise TokenError("EOF while scanning triple-quoted string", line, (lnum, 0), token_list) endmatch = endDFA.recognize(line) if endmatch >= 0: @@ -259,7 +259,6 @@ tok = Token(pytoken.STRING, token) token_list.append((tok, line, lnum, pos)) last_comment = '' - # token_list.append((STRING, token, spos, epos, line)) elif initial in namechars: # ordinary name tok = Token(pytoken.NAME, token) token_list.append((tok, line, lnum, pos)) Modified: pypy/dist/pypy/interpreter/pyparser/pytokenize.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pytokenize.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pytokenize.py Thu Aug 25 14:14:36 2005 @@ -20,7 +20,7 @@ from __future__ import generators from pypy.interpreter.pyparser import automata -__all__ = [ "tokenize", "generate_tokens", ] +__all__ = [ "tokenize" ] # ______________________________________________________________________ # Automatically generated DFA's (with one or two hand tweeks): From ludal at codespeak.net Thu Aug 25 14:15:59 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Thu, 25 Aug 2005 14:15:59 +0200 (CEST) Subject: [pypy-svn] r16481 - in pypy/dist/pypy: interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050825121559.AAACB27B51@code1.codespeak.net> Author: ludal Date: Thu Aug 25 14:15:58 2005 New Revision: 16481 Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/lib/_stablecompiler/transformer.py Log: - make sure recursion depth is enough for us Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Thu Aug 25 14:15:58 2005 @@ -33,6 +33,11 @@ import pypy.interpreter.pyparser.pytoken as token import sys +# transforming is requiring a lot of recursion depth so make sure we have enough +if sys.getrecursionlimit()<5000: + sys.setrecursionlimit(5000) + + class WalkerError(StandardError): pass Modified: pypy/dist/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/transformer.py Thu Aug 25 14:15:58 2005 @@ -31,6 +31,10 @@ import token import sys +# transforming is requiring a lot of recursion depth so make sure we have enough +if sys.getrecursionlimit()<5000: + sys.setrecursionlimit(5000) + class WalkerError(StandardError): pass From rxe at codespeak.net Thu Aug 25 14:39:06 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 14:39:06 +0200 (CEST) Subject: [pypy-svn] r16482 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050825123906.7303727B48@code1.codespeak.net> Author: rxe Date: Thu Aug 25 14:39:05 2005 New Revision: 16482 Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c Log: Fix typo Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 14:39:05 2005 @@ -12,7 +12,7 @@ struct RPyMODF_RESULT; struct RPyFREXP_RESULT *ll_frexp_result__Float_Signed(double, int); -struct RPyMODF_RESULT *ll_frexp_result__Float_Float(double, double); +struct RPyMODF_RESULT *ll_modf_result__Float_Float(double, double); void prepare_and_raise_OverflowError(char *); void prepare_and_raise_ValueError(char *); @@ -82,7 +82,7 @@ LL_MATH_ERROR_RESET; fracpart = modf(x, &intpart); LL_MATH_CHECK_ERROR(fracpart, NULL); - return ll_modf_result(fracpart, intpart); + return ll_modf_result__Float_Float(fracpart, intpart); } /* simple math function */ From nik at codespeak.net Thu Aug 25 14:54:43 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 14:54:43 +0200 (CEST) Subject: [pypy-svn] r16483 - pypy/dist/pypy/module/_sre Message-ID: <20050825125443.8604A27B48@code1.codespeak.net> Author: nik Date: Thu Aug 25 14:54:42 2005 New Revision: 16483 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: came up with scheme that will allow me to gradually move over the opcode handlers from app- to interp-level. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Thu Aug 25 14:54:42 2005 @@ -20,7 +20,9 @@ 'getlower': 'interp_sre.getlower', '_State': 'interp_sre.make_state', '_MatchContext': 'interp_sre.make_context', - '_RepeatContext': 'interp_sre.make_repeat_context', + '_RepeatContext': 'interp_sre.make_repeat_context', + '_opcode_dispatch': 'interp_sre.opcode_dispatch', + '_opcode_is_at_interplevel': 'interp_sre.opcode_is_at_interplevel', '_check_charset': 'interp_sre.check_charset', '_at_dispatch': 'interp_sre.at_dispatch', '_category_dispatch': 'interp_sre.category_dispatch', Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 14:54:42 2005 @@ -438,8 +438,11 @@ del self.executing_contexts[id(context)] has_finished = generator.next() else: - method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown) - has_finished = method(self, context) + if _sre._opcode_is_at_interplevel(opcode): + has_finished = _sre._opcode_dispatch(opcode, context) + else: + method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown) + has_finished = method(self, context) if hasattr(has_finished, "next"): # avoid using the types module generator = has_finished has_finished = generator.next() @@ -447,19 +450,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def op_success(self, ctx): - # end of pattern - #self._log(ctx, "SUCCESS") - ctx.state.string_position = ctx.string_position - ctx.has_matched = True - return True - - def op_failure(self, ctx): - # immediate failure - #self._log(ctx, "FAILURE") - ctx.has_matched = False - return True - def general_op_literal(self, ctx, compare, decorate=lambda x: x): if ctx.at_end() or not compare(decorate(ord(ctx.peek_char())), decorate(ctx.peek_code(1))): Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 14:54:42 2005 @@ -252,6 +252,56 @@ last_position = interp_attrproperty_obj_w("w_last_position", W_RepeatContext), ) +#### Opcode dispatch + +def opcode_dispatch(space, w_opcode, w_context): + opcode = space.int_w(w_opcode) + if opcode >= len(opcode_dispatch_table): + return space.newbool(False) + return space.newbool(opcode_dispatch_table[opcode](space, w_context)) + +def opcode_is_at_interplevel(space, w_opcode): + opcode = space.int_w(w_opcode) + return space.newbool(opcode_dispatch_table[opcode] is not None) + +def op_success(space, w_ctx): + # end of pattern + w_ctx.w_state.string_position = space.int_w(w_ctx.w_string_position) + w_ctx.w_has_matched = space.newbool(True) + return True + +def op_failure(space, w_ctx): + # immediate failure + w_ctx.w_has_matched = space.newbool(False) + return True + +opcode_dispatch_table = [ + op_failure, op_success, #FAILURE, SUCCESS, + None, None, #ANY, ANY_ALL, + None, None, #ASSERT, ASSERT_NOT, + None, #AT, + None, #BRANCH, + None, #CALL, + None, #CATEGORY, + None, None, #CHARSET, BIGCHARSET, + None, None, None, #GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE, + None, None, #IN, IN_IGNORE, + None, #INFO, + None, #JUMP, + None, None, #LITERAL, LITERAL_IGNORE, + None, #MARK, + None, #MAX_UNTIL, + None, #MIN_UNTIL, + None, None, #NOT_LITERAL, NOT_LITERAL_IGNORE, + None, #NEGATE, + None, #RANGE, + None, #REPEAT, + None, #REPEAT_ONE, + None, #SUBPATTERN, + None, #MIN_REPEAT_ONE +] + + #### Category helpers ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, From ericvrp at codespeak.net Thu Aug 25 15:02:17 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 15:02:17 +0200 (CEST) Subject: [pypy-svn] r16485 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825130217.329A927B48@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 15:02:16 2005 New Revision: 16485 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py Log: added DEFAULT_INTERNAL setting Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Thu Aug 25 15:02:16 2005 @@ -4,8 +4,9 @@ log = log.codewriter -DEFAULT_TAIL = 'tail' #or '' -DEFAULT_CCONV = 'fastcc' #or 'ccc' +DEFAULT_TAIL = '' #/tail +DEFAULT_CCONV = 'ccc' #ccc/fastcc +DEFAULT_INTERNAL = '' #/internal class CodeWriter(object): def __init__(self, f, word, uword, show_line_number=False): @@ -39,7 +40,7 @@ self.append(" %s:" % name) def globalinstance(self, name, typeandata): - self.append("%s = internal global %s" % (name, typeandata)) + self.append("%s = %s global %s" % (name, DEFAULT_INTERNAL, typeandata)) def structdef(self, name, typereprs): self.append("%s = type { %s }" %(name, ", ".join(typereprs))) @@ -79,7 +80,7 @@ if is_entrynode: linkage_type = '' else: - linkage_type = 'internal ' + linkage_type = DEFAULT_INTERNAL + ' ' self.append("%s%s %s {" % (linkage_type, cconv, decl,)) def closefunc(self): From ericvrp at codespeak.net Thu Aug 25 15:11:13 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 15:11:13 +0200 (CEST) Subject: [pypy-svn] r16487 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825131113.73AAA27B4B@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 15:11:12 2005 New Revision: 16487 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: * cleanup * using DEFAULT_INTERNAL tag Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 15:11:12 2005 @@ -15,7 +15,8 @@ from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir -from pypy.translator.llvm2.codewriter import CodeWriter +from pypy.translator.llvm2.codewriter import CodeWriter, \ + DEFAULT_INTERNAL, DEFAULT_TAIL, DEFAULT_CCONV from pypy.translator.llvm2 import extfuncnode from pypy.translator.llvm2.module.extfunction import extdeclarations, \ extfunctions, gc_boehm, gc_disabled, dependencies @@ -53,7 +54,7 @@ returntype, s = line.split(' ', 1) funcname , s = s.split('(', 1) funcnames[funcname] = True - line = 'internal fastcc ' + line + line = '%s %s %s' % (DEFAULT_INTERNAL, DEFAULT_CCONV, line,) ll_lines.append(line) #patch calls to function that we just declared fastcc @@ -64,14 +65,14 @@ cconv = 'ccc' for funcname in funcnames.keys(): if line.find(funcname) >= 0: - cconv = 'fastcc' + cconv = DEFAULT_CCONV break line = "%scall %s %s" % (line[:i], cconv, line[i+len(calltag):]) if line[:len(declaretag)] == declaretag: cconv = 'ccc' for funcname in funcnames.keys(): if line.find(funcname) >= 0: - cconv = 'fastcc' + cconv = DEFAULT_CCONV break line = "declare %s %s" % (cconv, line[len(declaretag):]) ll_lines2.append(line) @@ -177,9 +178,6 @@ j = os.path.join p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") return get_ll(open(p).read(), extern_dir, ['ll_math_frexp', 'll_math_is_error']) - - def replace_with_machine_words(self, s): - return s.replace('UINT',self.db.get_machine_uword()).replace('INT',self.db.get_machine_word()) def gen_llvm_source(self, func=None): if self.debug: print 'gen_llvm_source begin) ' + time.ctime() @@ -258,7 +256,7 @@ if self.debug: print 'gen_llvm_source extdeclarations) ' + time.ctime() nl(); comment("Function Prototypes") ; nl() - for extdecl in self.replace_with_machine_words(extdeclarations).split('\n'): + for extdecl in extdeclarations.split('\n'): codewriter.append(extdecl) if self.debug: print 'gen_llvm_source self._debug_prototype) ' + time.ctime() @@ -276,7 +274,7 @@ gc_funcs = gc_boehm else: gc_funcs = gc_disabled - for gc_func in self.replace_with_machine_words(gc_funcs).split('\n'): + for gc_func in gc_funcs.split('\n'): codewriter.append(gc_func) if self.debug: print 'gen_llvm_source typ_decl.writeimpl) ' + time.ctime() @@ -296,7 +294,7 @@ no_result = '0' codewriter.newline() codewriter.append("ccc %s%%__entrypoint__%s {" % (t[0], t[1])) - codewriter.append(" %%result = invoke fastcc %s%%%s to label %%no_exception except label %%exception" % (t[0], t[1])) + codewriter.append(" %%result = invoke %s %s%%%s to label %%no_exception except label %%exception" % (DEFAULT_CCONV, t[0], t[1])) codewriter.newline() codewriter.append("no_exception:") codewriter.append(" store %RPYTHON_EXCEPTION_VTABLE* null, %RPYTHON_EXCEPTION_VTABLE** %last_exception_type") @@ -331,7 +329,7 @@ codewriter.comment('XXX: Error: ' + msg) #raise Exception('primitive function %s has no implementation' %(dep,)) continue - for extfunc in self.replace_with_machine_words(llvm_code).split('\n'): + for extfunc in llvm_code.split('\n'): codewriter.append(extfunc) depdone[dep] = True From ericvrp at codespeak.net Thu Aug 25 15:12:37 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 15:12:37 +0200 (CEST) Subject: [pypy-svn] r16488 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825131237.4C00027B4B@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 15:12:36 2005 New Revision: 16488 Modified: pypy/dist/pypy/translator/llvm2/codewriter.py Log: fixed usage of tail Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Thu Aug 25 15:12:36 2005 @@ -170,7 +170,7 @@ def debugcomment(self, tempname, len, tmpname): word = self.word - res = "%s = tail call ccc %(word)s (sbyte*, ...)* %%printf(" % locals() + res = "%s = call ccc %(word)s (sbyte*, ...)* %%printf(" % locals() res += "sbyte* getelementptr ([%s x sbyte]* %s, %(word)s 0, %(word)s 0) )" % locals() res = res % (tmpname, len, tmpname) self.indent(res) From ericvrp at codespeak.net Thu Aug 25 15:14:28 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 15:14:28 +0200 (CEST) Subject: [pypy-svn] r16489 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050825131428.36ADD27B4B@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 15:14:26 2005 New Revision: 16489 Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/ll_strtod.py pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py Log: * removed UINT and INT's (no longer used) * added DEFAULT_INTERNAL usage Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 25 15:14:26 2005 @@ -1,40 +1,43 @@ +import py +from pypy.translator.llvm2.codewriter import DEFAULT_INTERNAL, DEFAULT_CCONV + extdeclarations = """;rpython stuff ;gc-type dependent mallocs -declare fastcc sbyte* %gc_malloc(UINT) -declare fastcc sbyte* %gc_malloc_atomic(UINT) +declare %(DEFAULT_CCONV)s sbyte* %%gc_malloc(uint) +declare %(DEFAULT_CCONV)s sbyte* %%gc_malloc_atomic(uint) ;exception handling globals -%last_exception_type = global %RPYTHON_EXCEPTION_VTABLE* null -%last_exception_value = global %RPYTHON_EXCEPTION* null -""" - -gc_boehm = """declare ccc sbyte* %GC_malloc(UINT) -declare ccc sbyte* %GC_malloc_atomic(UINT) - -internal fastcc sbyte* %gc_malloc(UINT %n) { - %ptr = call ccc sbyte* %GC_malloc(UINT %n) - ret sbyte* %ptr +%%last_exception_type = global %%RPYTHON_EXCEPTION_VTABLE* null +%%last_exception_value = global %%RPYTHON_EXCEPTION* null +""" % locals() + +gc_boehm = """declare ccc sbyte* %%GC_malloc(uint) +declare ccc sbyte* %%GC_malloc_atomic(uint) + +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc(uint %%n) { + %%ptr = call ccc sbyte* %%GC_malloc(uint %%n) + ret sbyte* %%ptr } -internal fastcc sbyte* %gc_malloc_atomic(UINT %n) { - %ptr = call ccc sbyte* %GC_malloc_atomic(UINT %n) - ret sbyte* %ptr +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc_atomic(uint %%n) { + %%ptr = call ccc sbyte* %%GC_malloc_atomic(uint %%n) + ret sbyte* %%ptr } -""" +""" % locals() -gc_disabled = """internal fastcc sbyte* %gc_malloc(UINT %n) { - %nn = cast UINT %n to uint - %ptr = malloc sbyte, uint %nn - ret sbyte* %ptr +gc_disabled = """%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc(uint %%n) { + %%nn = cast uint %%n to uint + %%ptr = malloc sbyte, uint %%nn + ret sbyte* %%ptr } -internal fastcc sbyte* %gc_malloc_atomic(UINT %n) { - %nn = cast UINT %n to uint - %ptr = malloc sbyte, uint %nn - ret sbyte* %ptr +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc_atomic(uint %%n) { + %%nn = cast uint %%n to uint + %%ptr = malloc sbyte, uint %%nn + ret sbyte* %%ptr } -""" +""" % locals() extfunctions = {} #dependencies, llvm-code Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Thu Aug 25 15:14:26 2005 @@ -19,11 +19,11 @@ declare ccc double %atan2(double,double) declare ccc double %fmod(double,double) -%__ll_math_frexp = internal constant [12 x sbyte] c"frexp......\\00" -%__ll_math_hypot = internal constant [12 x sbyte] c"hypot......\\00" -%__ll_math_ldexp = internal constant [12 x sbyte] c"ldexp......\\00" -%__ll_math_modf = internal constant [12 x sbyte] c"modf.......\\00" -%__ll_math_pow = internal constant [12 x sbyte] c"pow........\\00" +%__ll_math_frexp = constant [12 x sbyte] c"frexp......\\00" +%__ll_math_hypot = constant [12 x sbyte] c"hypot......\\00" +%__ll_math_ldexp = constant [12 x sbyte] c"ldexp......\\00" +%__ll_math_modf = constant [12 x sbyte] c"modf.......\\00" +%__ll_math_pow = constant [12 x sbyte] c"pow........\\00" """ extfunctions = {} @@ -36,7 +36,7 @@ ] simple_function_template = """ -internal fastcc double %%ll_math_%(function)s(%(params)s) { +ccc double %%ll_math_%(function)s(%(params)s) { %%t = call ccc double %%%(function)s(%(params)s) ret double %%t } @@ -48,29 +48,29 @@ extfunctions["%ll_math_" + function] = ((), simple_function_template % locals()) extfunctions["%ll_math_hypot"] = (("%__debug",), """ -internal fastcc double %ll_math_hypot(double %x, double %y) { - call fastcc void %__debug([12 x sbyte]* %__ll_math_hypot) ; XXX: TODO: ll_math_hypot +ccc double %ll_math_hypot(double %x, double %y) { + call ccc void %__debug([12 x sbyte]* %__ll_math_hypot) ; XXX: TODO: ll_math_hypot ret double 0.0 } """) extfunctions["%ll_math_ldexp"] = (("%__debug",), """ -internal fastcc double %ll_math_ldexp(double %x, INT %y) { - call fastcc void %__debug([12 x sbyte]* %__ll_math_ldexp) ; XXX: TODO: ll_math_ldexp +ccc double %ll_math_ldexp(double %x, int %y) { + call ccc void %__debug([12 x sbyte]* %__ll_math_ldexp) ; XXX: TODO: ll_math_ldexp ret double 0.0 } """) extfunctions["%ll_math_modf"] = (("%__debug",), """ -internal fastcc %RPyMODF_RESULT* %ll_math_modf(double %x) { - call fastcc void %__debug([12 x sbyte]* %__ll_math_modf) ; XXX: TODO: ll_math_modf +ccc %RPyMODF_RESULT* %ll_math_modf(double %x) { + call ccc void %__debug([12 x sbyte]* %__ll_math_modf) ; XXX: TODO: ll_math_modf ret %RPyMODF_RESULT* null } """) extfunctions["%ll_math_pow"] = (("%__debug",), """ -internal fastcc double %ll_math_pow(double %x, double %y) { - call fastcc void %__debug([12 x sbyte]* %__ll_math_pow) ; XXX: TODO: ll_math_pow +ccc double %ll_math_pow(double %x, double %y) { + call ccc void %__debug([12 x sbyte]* %__ll_math_pow) ; XXX: TODO: ll_math_pow ret double 0.0 } """) Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Thu Aug 25 15:14:26 2005 @@ -1,150 +1,160 @@ extdeclarations = """ ;ll_os.py -declare ccc INT %dup(INT) -declare ccc void %close(INT) -declare ccc INT %open(sbyte*, INT, INT) -declare ccc INT %write(INT, sbyte*, INT) -declare ccc INT %read(INT, sbyte*, INT) -declare ccc sbyte* %strncpy(sbyte*, sbyte*, INT) -declare ccc INT %isatty(INT) -declare ccc INT %stat(sbyte*, [32 x INT]*) -declare ccc INT %fstat(INT, [32 x INT]*) -declare ccc INT %lseek(INT, INT, INT) -declare ccc INT %ftruncate(INT, INT) -declare ccc sbyte* %getcwd(sbyte*, INT) - -%errno = external global INT - -%__ll_os_getcwd = internal constant [12 x sbyte] c"getcwd.....\\00" -%__ll_os_ftruncate = internal constant [12 x sbyte] c"ftruncate..\\00" -%__ll_os_lseek = internal constant [12 x sbyte] c"lseek......\\00" -%__ll_os_stat = internal constant [12 x sbyte] c"stat.......\\00" -%__ll_os_fstat = internal constant [12 x sbyte] c"fstat......\\00" +declare ccc int %system(sbyte*) +declare ccc int %dup(int) +declare ccc void %close(int) +declare ccc int %open(sbyte*, int, int) +declare ccc int %write(int, sbyte*, int) +declare ccc int %read(int, sbyte*, int) +declare ccc sbyte* %strncpy(sbyte*, sbyte*, int) +declare ccc int %isatty(int) +declare ccc int %stat(sbyte*, [32 x int]*) +declare ccc int %fstat(int, [32 x int]*) +declare ccc int %lseek(int, int, int) +declare ccc int %ftruncate(int, int) +declare ccc sbyte* %getcwd(sbyte*, int) + +%errno = external global int + +%__ll_os_getcwd = constant [12 x sbyte] c"getcwd.....\\00" +%__ll_os_ftruncate = constant [12 x sbyte] c"ftruncate..\\00" +%__ll_os_lseek = constant [12 x sbyte] c"lseek......\\00" +%__ll_os_stat = constant [12 x sbyte] c"stat.......\\00" +%__ll_os_fstat = constant [12 x sbyte] c"fstat......\\00" """ extfunctions = {} +extfunctions["%ll_os_system"] = (("%cast",), """ +ccc int %ll_os_system(%RPyString* %structstring) { + %dest = call ccc sbyte* %cast(%RPyString* %structstring) + %ret = call ccc int %system(sbyte* %dest) + ret int %ret +} + +""") + extfunctions["%ll_os_dup"] = ((), """ -internal fastcc INT %ll_os_dup(INT %fd) { - %ret = call ccc INT %dup(INT %fd) - ret INT %ret +ccc int %ll_os_dup(int %fd) { + %ret = call ccc int %dup(int %fd) + ret int %ret } """) extfunctions["%ll_os_getcwd"] = (("%string_to_RPyString", "%__debug"), """ -internal fastcc %RPyString* %ll_os_getcwd() { +ccc %RPyString* %ll_os_getcwd() { - call fastcc void %__debug([12 x sbyte]* %__ll_os_getcwd) ; XXX: Test: ll_os_getcwd + call ccc void %__debug([12 x sbyte]* %__ll_os_getcwd) ; XXX: Test: ll_os_getcwd - %s = alloca sbyte, UINT 1024 - %res = call ccc sbyte* %getcwd(sbyte* %s, INT 1023) + %s = alloca sbyte, uint 1024 + %res = call ccc sbyte* %getcwd(sbyte* %s, int 1023) ;if %res == null: raise... - %cwd = call fastcc %RPyString* %string_to_RPyString(sbyte* %s) + %cwd = call ccc %RPyString* %string_to_RPyString(sbyte* %s) ret %RPyString* %cwd } """) extfunctions["%ll_os_close"] = ((), """ -internal fastcc void %ll_os_close(INT %fd) { - call ccc void %close(INT %fd) +ccc void %ll_os_close(int %fd) { + call ccc void %close(int %fd) ret void } """) extfunctions["%ll_os_open"] = (("%cast",), """ -internal fastcc INT %ll_os_open(%RPyString* %structstring, INT %flag, INT %mode) { - %dest = call fastcc sbyte* %cast(%RPyString* %structstring) - %fd = call ccc INT %open(sbyte* %dest, INT %flag, INT %mode) - ret INT %fd +ccc int %ll_os_open(%RPyString* %structstring, int %flag, int %mode) { + %dest = call ccc sbyte* %cast(%RPyString* %structstring) + %fd = call ccc int %open(sbyte* %dest, int %flag, int %mode) + ret int %fd } """) extfunctions["%ll_os_write"] = (("%cast",), """ -internal fastcc INT %ll_os_write(INT %fd, %RPyString* %structstring) { +ccc int %ll_os_write(int %fd, %RPyString* %structstring) { %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 - %reallength = load INT* %reallengthptr - %dest = call fastcc sbyte* %cast(%RPyString* %structstring) - %byteswritten = call ccc INT %write(INT %fd, sbyte* %dest, INT %reallength) - ret INT %byteswritten + %reallength = load int* %reallengthptr + %dest = call ccc sbyte* %cast(%RPyString* %structstring) + %byteswritten = call ccc int %write(int %fd, sbyte* %dest, int %reallength) + ret int %byteswritten } """) extfunctions["%ll_read_into"] = ((), """ -internal fastcc INT %ll_read_into(INT %fd, %RPyString* %structstring) { +ccc int %ll_read_into(int %fd, %RPyString* %structstring) { %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 - %reallength = load INT* %reallengthptr + %reallength = load int* %reallengthptr %destptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 %dest = cast [0 x sbyte]* %destptr to sbyte* - %bytesread = call ccc INT %read(INT %fd, sbyte* %dest, INT %reallength) - ret INT %bytesread + %bytesread = call ccc int %read(int %fd, sbyte* %dest, int %reallength) + ret int %bytesread } """) extfunctions["%ll_os_isatty"] = ((), """ -internal fastcc bool %ll_os_isatty(INT %fd) { - %ret = call ccc INT %isatty(INT %fd) - %ret.bool = cast INT %ret to bool +ccc bool %ll_os_isatty(int %fd) { + %ret = call ccc int %isatty(int %fd) + %ret.bool = cast int %ret to bool ret bool %ret.bool } """) extfunctions["%ll_os_ftruncate"] = (("%__debug",), """ -internal fastcc void %ll_os_ftruncate(INT %fd, INT %length) { - call fastcc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: Test: ll_os_ftruncate - %res = call ccc INT %ftruncate(INT %fd, INT %length) +ccc void %ll_os_ftruncate(int %fd, int %length) { + call ccc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: Test: ll_os_ftruncate + %res = call ccc int %ftruncate(int %fd, int %length) ;if res < 0 raise... ret void } """) extfunctions["%ll_os_lseek"] = (("%__debug",), """ -internal fastcc INT %ll_os_lseek(INT %fd, INT %pos, INT %how) { - call fastcc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: Test: ll_os_lseek +ccc int %ll_os_lseek(int %fd, int %pos, int %how) { + call ccc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: Test: ll_os_lseek ;TODO: determine correct %how - %res = call ccc INT %lseek(INT %fd, INT %pos, INT %how) + %res = call ccc int %lseek(int %fd, int %pos, int %how) ;if res < 0 raise... - ret INT %res + ret int %res } """) extfunctions["%_stat_construct_result_helper"] = ((), """ -internal fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x INT]* %src) { +ccc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %src) { - %src0ptr = getelementptr [32 x INT]* %src, int 0, uint 4 ;st_mode - %src1ptr = getelementptr [32 x INT]* %src, int 0, uint 3 ;st_ino - %src2ptr = getelementptr [32 x INT]* %src, int 0, uint 0 ;st_dev - %src3ptr = getelementptr [32 x INT]* %src, int 0, uint 5 ;st_nlink - %src4ptr = getelementptr [32 x INT]* %src, int 0, uint 6 ;st_uid - %src5ptr = getelementptr [32 x INT]* %src, int 0, uint 7 ;st_gid - %src6ptr = getelementptr [32 x INT]* %src, int 0, uint 11 ;st_size - %src7ptr = getelementptr [32 x INT]* %src, int 0, uint 14 ;st_atime - %src8ptr = getelementptr [32 x INT]* %src, int 0, uint 16 ;st_mtime - %src9ptr = getelementptr [32 x INT]* %src, int 0, uint 18 ;st_ctime - - %src0 = load INT* %src0ptr - %src1 = load INT* %src1ptr - %src2 = load INT* %src2ptr - %src3 = load INT* %src3ptr - %src4 = load INT* %src4ptr - %src5 = load INT* %src5ptr - %src6 = load INT* %src6ptr - %src7 = load INT* %src7ptr - %src8 = load INT* %src8ptr - %src9 = load INT* %src9ptr + %src0ptr = getelementptr [32 x int]* %src, int 0, uint 4 ;st_mode + %src1ptr = getelementptr [32 x int]* %src, int 0, uint 3 ;st_ino + %src2ptr = getelementptr [32 x int]* %src, int 0, uint 0 ;st_dev + %src3ptr = getelementptr [32 x int]* %src, int 0, uint 5 ;st_nlink + %src4ptr = getelementptr [32 x int]* %src, int 0, uint 6 ;st_uid + %src5ptr = getelementptr [32 x int]* %src, int 0, uint 7 ;st_gid + %src6ptr = getelementptr [32 x int]* %src, int 0, uint 11 ;st_size + %src7ptr = getelementptr [32 x int]* %src, int 0, uint 14 ;st_atime + %src8ptr = getelementptr [32 x int]* %src, int 0, uint 16 ;st_mtime + %src9ptr = getelementptr [32 x int]* %src, int 0, uint 18 ;st_ctime + + %src0 = load int* %src0ptr + %src1 = load int* %src1ptr + %src2 = load int* %src2ptr + %src3 = load int* %src3ptr + %src4 = load int* %src4ptr + %src5 = load int* %src5ptr + %src6 = load int* %src6ptr + %src7 = load int* %src7ptr + %src8 = load int* %src8ptr + %src9 = load int* %src9ptr %malloc.Size = getelementptr %RPySTAT_RESULT* null, uint 1 - %malloc.SizeU = cast %RPySTAT_RESULT* %malloc.Size to UINT - %malloc.Ptr = call fastcc sbyte* %gc_malloc_atomic(UINT %malloc.SizeU) + %malloc.SizeU = cast %RPySTAT_RESULT* %malloc.Size to uint + %malloc.Ptr = call ccc sbyte* %gc_malloc_atomic(uint %malloc.SizeU) %dest = cast sbyte* %malloc.Ptr to %RPySTAT_RESULT* %dest0ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 0 @@ -158,60 +168,60 @@ %dest8ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 8 %dest9ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 9 - store INT %src0, INT* %dest0ptr - store INT %src1, INT* %dest1ptr - store INT %src2, INT* %dest2ptr - store INT %src3, INT* %dest3ptr - store INT %src4, INT* %dest4ptr - store INT %src5, INT* %dest5ptr - store INT %src6, INT* %dest6ptr - store INT %src7, INT* %dest7ptr - store INT %src8, INT* %dest8ptr - store INT %src9, INT* %dest9ptr + store int %src0, int* %dest0ptr + store int %src1, int* %dest1ptr + store int %src2, int* %dest2ptr + store int %src3, int* %dest3ptr + store int %src4, int* %dest4ptr + store int %src5, int* %dest5ptr + store int %src6, int* %dest6ptr + store int %src7, int* %dest7ptr + store int %src8, int* %dest8ptr + store int %src9, int* %dest9ptr ret %RPySTAT_RESULT* %dest } """) extfunctions["%ll_os_stat"] = (("%cast", "%__debug", "%_stat_construct_result_helper"), """ -internal fastcc %RPySTAT_RESULT* %ll_os_stat(%RPyString* %s) { +ccc %RPySTAT_RESULT* %ll_os_stat(%RPyString* %s) { - call fastcc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat + call ccc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat - %st = alloca [32 x INT] - %filename = call fastcc sbyte* %cast(%RPyString* %s) - %error = call ccc INT %stat(sbyte* %filename, [32 x INT]* %st) - %cond = seteq INT %error, 0 + %st = alloca [32 x int] + %filename = call ccc sbyte* %cast(%RPyString* %s) + %error = call ccc int %stat(sbyte* %filename, [32 x int]* %st) + %cond = seteq int %error, 0 br bool %cond, label %cool, label %bwa bwa: - %errno_ = load INT* %errno - call fastcc void %ll_raise_OSError__Signed(INT %errno_) + %errno_ = load int* %errno + call ccc void %ll_raise_OSError__Signed(int %errno_) ret %RPySTAT_RESULT* null cool: - %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x INT]* %st) + %result = call ccc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) ret %RPySTAT_RESULT* %result } """) extfunctions["%ll_os_fstat"] = (("%__debug", "%_stat_construct_result_helper"), """ -internal fastcc %RPySTAT_RESULT* %ll_os_fstat(INT %fd) { +ccc %RPySTAT_RESULT* %ll_os_fstat(int %fd) { - call fastcc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat + call ccc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat - %st = alloca [32 x INT] - %error = call ccc INT %fstat(INT %fd, [32 x INT]* %st) - %cond = seteq INT %error, 0 + %st = alloca [32 x int] + %error = call ccc int %fstat(int %fd, [32 x int]* %st) + %cond = seteq int %error, 0 br bool %cond, label %cool, label %bwa bwa: - %errno_ = load INT* %errno - call fastcc void %ll_raise_OSError__Signed(INT %errno_) + %errno_ = load int* %errno + call ccc void %ll_raise_OSError__Signed(int %errno_) ret %RPySTAT_RESULT* null cool: - %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x INT]* %st) + %result = call ccc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) ret %RPySTAT_RESULT* %result } Modified: pypy/dist/pypy/translator/llvm2/module/ll_strtod.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_strtod.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_strtod.py Thu Aug 25 15:14:26 2005 @@ -1,21 +1,21 @@ extdeclarations = """ ;ll_strtod.py -%__ll_strtod_formatd = internal constant [12 x sbyte] c"formatd....\\00" -%__ll_strtod_parts_to_float = internal constant [12 x sbyte] c"parts2flt..\\00" +%__ll_strtod_formatd = constant [12 x sbyte] c"formatd....\\00" +%__ll_strtod_parts_to_float = constant [12 x sbyte] c"parts2flt..\\00" """ extfunctions = {} extfunctions["%ll_strtod_formatd"] = (("%__debug",), """ -internal fastcc %RPyString* %ll_strtod_formatd(%RPyString* %s, double %x) { - call fastcc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd +ccc %RPyString* %ll_strtod_formatd(%RPyString* %s, double %x) { + call ccc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd ret %RPyString* null } """) extfunctions["%ll_strtod_parts_to_float"] = (("%__debug",), """ -internal fastcc double %ll_strtod_parts_to_float(%RPyString* s0, %RPyString* s1, %RPyString* s2, %RPyString* s3) { - call fastcc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float +ccc double %ll_strtod_parts_to_float(%RPyString* s0, %RPyString* s1, %RPyString* s2, %RPyString* s3) { + call ccc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float ret double 0.0 } """) Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Thu Aug 25 15:14:26 2005 @@ -1,81 +1,81 @@ extdeclarations = ''' ;ll_time.py -%struct.timeval = type { INT, INT } -%struct.timezone = type { INT, INT } -%typedef.fd_set = type { [32 x INT] } +%struct.timeval = type { int, int } +%struct.timezone = type { int, int } +%typedef.fd_set = type { [32 x int] } -%.str_xxx1 = internal constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] +%.str_xxx1 = constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] declare ccc double %floor(double) declare ccc double %fmod(double, double) -declare ccc INT %clock() -declare ccc INT %select(INT, %typedef.fd_set*, %typedef.fd_set*, %typedef.fd_set*, %struct.timeval*) -declare ccc INT %gettimeofday(%struct.timeval*, %struct.timeval*) -declare ccc INT %time( INT* ) +declare ccc int %clock() +declare ccc int %select(int, %typedef.fd_set*, %typedef.fd_set*, %typedef.fd_set*, %struct.timeval*) +declare ccc int %gettimeofday(%struct.timeval*, %struct.timeval*) +declare ccc int %time( int* ) ''' extfunctions = {} extfunctions["%ll_time_time"] = ((), """ -internal fastcc double %ll_time_time() { +ccc double %ll_time_time() { %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] - %secs = alloca INT ; [#uses=2] - %tmp.0 = call INT %gettimeofday( %struct.timeval* %t, %struct.timeval* null ) ; [#uses=1] - %tmp.1 = seteq INT %tmp.0, 0 ; [#uses=2] - %tmp.2 = cast bool %tmp.1 to INT ; [#uses=0] + %secs = alloca int ; [#uses=2] + %tmp.0 = call int %gettimeofday( %struct.timeval* %t, %struct.timeval* null ) ; [#uses=1] + %tmp.1 = seteq int %tmp.0, 0 ; [#uses=2] + %tmp.2 = cast bool %tmp.1 to int ; [#uses=0] br bool %tmp.1, label %then, label %endif then: ; preds = %entry %tmp.3 = getelementptr %struct.timeval* %t, int 0, uint 0 ; [#uses=1] - %tmp.4 = load INT* %tmp.3 ; [#uses=1] - %tmp.5 = cast INT %tmp.4 to double ; [#uses=1] + %tmp.4 = load int* %tmp.3 ; [#uses=1] + %tmp.5 = cast int %tmp.4 to double ; [#uses=1] %tmp.6 = getelementptr %struct.timeval* %t, int 0, uint 1 ; [#uses=1] - %tmp.7 = load INT* %tmp.6 ; [#uses=1] - %tmp.8 = cast INT %tmp.7 to double ; [#uses=1] + %tmp.7 = load int* %tmp.6 ; [#uses=1] + %tmp.8 = cast int %tmp.7 to double ; [#uses=1] %tmp.9 = mul double %tmp.8, 1.000000e-06 ; [#uses=1] %tmp.10 = add double %tmp.5, %tmp.9 ; [#uses=1] ret double %tmp.10 endif: ; preds = %entry - %tmp.11 = call INT %time( INT* %secs ) ; [#uses=0] - %tmp.12 = load INT* %secs ; [#uses=1] - %tmp.13 = cast INT %tmp.12 to double ; [#uses=1] + %tmp.11 = call int %time( int* %secs ) ; [#uses=0] + %tmp.12 = load int* %secs ; [#uses=1] + %tmp.13 = cast int %tmp.12 to double ; [#uses=1] ret double %tmp.13 } """) extfunctions["%ll_time_clock"] = ((), """ -internal fastcc double %ll_time_clock() { +ccc double %ll_time_clock() { entry: - %tmp.0 = call INT %clock( ) ; [#uses=1] - %tmp.1 = cast INT %tmp.0 to double ; [#uses=1] + %tmp.0 = call int %clock( ) ; [#uses=1] + %tmp.1 = cast int %tmp.0 to double ; [#uses=1] %tmp.2 = div double %tmp.1, 1.000000e+06 ; [#uses=1] ret double %tmp.2 } """) extfunctions["%ll_time_sleep"] = ((), """ -internal fastcc void %ll_time_sleep(double %secs) { +ccc void %ll_time_sleep(double %secs) { entry: %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] %tmp.0 = call double %fmod( double %secs, double 1.000000e+00 ) ; [#uses=1] %tmp.2 = call double %floor( double %secs ) ; [#uses=1] %tmp.4 = getelementptr %struct.timeval* %t, int 0, uint 0 ; [#uses=1] - %tmp.6 = cast double %tmp.2 to INT ; [#uses=1] - store INT %tmp.6, INT* %tmp.4 + %tmp.6 = cast double %tmp.2 to int ; [#uses=1] + store int %tmp.6, int* %tmp.4 %tmp.7 = getelementptr %struct.timeval* %t, int 0, uint 1 ; [#uses=1] %tmp.9 = mul double %tmp.0, 1.000000e+06 ; [#uses=1] - %tmp.10 = cast double %tmp.9 to INT ; [#uses=1] - store INT %tmp.10, INT* %tmp.7 - %tmp.11 = call INT %select( INT 0, %typedef.fd_set* null, %typedef.fd_set* null, %typedef.fd_set* null, %struct.timeval* %t ) ; [#uses=1] - %tmp.12 = setne INT %tmp.11, 0 ; [#uses=2] - %tmp.13 = cast bool %tmp.12 to INT ; [#uses=0] + %tmp.10 = cast double %tmp.9 to int ; [#uses=1] + store int %tmp.10, int* %tmp.7 + %tmp.11 = call int %select( int 0, %typedef.fd_set* null, %typedef.fd_set* null, %typedef.fd_set* null, %struct.timeval* %t ) ; [#uses=1] + %tmp.12 = setne int %tmp.11, 0 ; [#uses=2] + %tmp.13 = cast bool %tmp.12 to int ; [#uses=0] br bool %tmp.12, label %then.1, label %return then.1: ; preds = %entry - ; XXX disabled for now: call void %RaiseSimpleException( INT 1, sbyte* getelementptr ([16 x sbyte]* %.str_xxx1, INT 0, INT 0) ) + ; XXX disabled for now: call void %RaiseSimpleException( int 1, sbyte* getelementptr ([16 x sbyte]* %.str_xxx1, int 0, int 0) ) ret void return: ; preds = %entry Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 15:14:26 2005 @@ -1,95 +1,98 @@ -extdeclarations = """ -declare ccc double %pow(double, double) -declare ccc double %fmod(double, double) -declare ccc INT %puts(sbyte*) -declare ccc INT %strlen(sbyte*) -declare ccc INT %strcmp(sbyte*, sbyte*) -declare ccc sbyte* %memset(sbyte*, INT, UINT) +import py +from pypy.translator.llvm2.codewriter import DEFAULT_INTERNAL, DEFAULT_CCONV -%__print_debug_info = internal global bool false -%__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" -""" +extdeclarations = """ +declare ccc double %%pow(double, double) +declare ccc double %%fmod(double, double) +declare ccc int %%puts(sbyte*) +declare ccc int %%strlen(sbyte*) +declare ccc int %%strcmp(sbyte*, sbyte*) +declare ccc sbyte* %%memset(sbyte*, int, uint) + +%%__print_debug_info = %(DEFAULT_INTERNAL)s global bool false +%%__print_debug_info_option = %(DEFAULT_INTERNAL)s constant [19 x sbyte] c"--print-debug-info\\00" +""" % locals() extfunctions = {} extfunctions["%__debug"] = ((), """ -internal fastcc void %__debug([12 x sbyte]* %msg12) { - %cond = load bool* %__print_debug_info - br bool %cond, label %print_it, label %do_nothing +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s void %%__debug([12 x sbyte]* %%msg12) { + %%cond = load bool* %%__print_debug_info + br bool %%cond, label %%print_it, label %%do_nothing do_nothing: ret void print_it: - %msg = getelementptr [12 x sbyte]* %msg12, int 0, int 0 - call int %puts(sbyte* %msg) + %%msg = getelementptr [12 x sbyte]* %%msg12, int 0, int 0 + call int %%puts(sbyte* %%msg) ret void } -""") +""" % locals()) extfunctions["%cast"] = (("%string_to_RPyString",), """ -internal fastcc sbyte* %cast(%RPyString* %structstring) { - %source1ptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 - %source1 = cast [0 x sbyte]* %source1ptr to sbyte* - ret sbyte* %source1 +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%cast(%%RPyString* %%structstring) { + %%source1ptr = getelementptr %%RPyString* %%structstring, int 0, uint 1, uint 1 + %%source1 = cast [0 x sbyte]* %%source1ptr to sbyte* + ret sbyte* %%source1 } -""") +""" % locals()) extfunctions["%string_to_RPyString"] = ((), """ -internal fastcc %RPyString* %string_to_RPyString(sbyte* %s) { - %len = call ccc INT %strlen(sbyte* %s) - %rpy = call fastcc %RPyString* %RPyString_New__Signed(INT %len) - %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 - %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s %%RPyString* %%string_to_RPyString(sbyte* %%s) { + %%len = call ccc int %%strlen(sbyte* %%s) + %%rpy = call %(DEFAULT_CCONV)s %%RPyString* %%RPyString_New__Signed(int %%len) + %%rpystrptr = getelementptr %%RPyString* %%rpy, int 0, uint 1, uint 1 + %%rpystr = cast [0 x sbyte]* %%rpystrptr to sbyte* - call ccc sbyte* %strncpy(sbyte* %rpystr, sbyte* %s, INT %len) + call ccc sbyte* %%strncpy(sbyte* %%rpystr, sbyte* %%s, int %%len) - ret %RPyString* %rpy + ret %%RPyString* %%rpy } -""") +""" % locals()) #abs functions extfunctions["%int_abs"] = ((), """ -internal fastcc INT %int_abs(INT %x) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_abs(int %%x) { block0: - %cond1 = setge INT %x, 0 - br bool %cond1, label %return_block, label %block1 + %%cond1 = setge int %%x, 0 + br bool %%cond1, label %%return_block, label %%block1 block1: - %x2 = sub INT 0, %x - br label %return_block + %%x2 = sub int 0, %%x + br label %%return_block return_block: - %result = phi INT [%x, %block0], [%x2, %block1] - ret INT %result + %%result = phi int [%%x, %%block0], [%%x2, %%block1] + ret int %%result } -""") +""" % locals()) extfunctions["%float_abs"] = ((), """ -internal fastcc double %float_abs(double %x) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s double %%float_abs(double %%x) { block0: - %cond1 = setge double %x, 0.0 - br bool %cond1, label %return_block, label %block1 + %%cond1 = setge double %%x, 0.0 + br bool %%cond1, label %%return_block, label %%block1 block1: - %x2 = sub double 0.0, %x - br label %return_block + %%x2 = sub double 0.0, %%x + br label %%return_block return_block: - %result = phi double [%x, %block0], [%x2, %block1] - ret double %result + %%result = phi double [%%x, %%block0], [%%x2, %%block1] + ret double %%result } -""") +""" % locals()) #prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ -internal fastcc void %%__prepare_%(exc)s() { - %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s void %%__prepare_%(exc)s() { + %%exception_value = call %(DEFAULT_CCONV)s %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type @@ -101,9 +104,9 @@ #prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%prepare_and_raise_%(exc)s" % locals()] = ((), """ -internal fastcc void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { ;XXX %%msg not used right now! - %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() + %%exception_value = call %(DEFAULT_CCONV)s %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type @@ -119,36 +122,36 @@ %%cond = seteq %s %%y, 0 br bool %%cond, label %%is_0, label %%is_not_0 is_0: - call fastcc void %%__prepare_ZeroDivisionError() + call %s void %%__prepare_ZeroDivisionError() unwind is_not_0: """ -int_zer_test = zer_test % ('int',) -double_zer_test = zer_test % ('double',) +int_zer_test = zer_test % ('int' , DEFAULT_CCONV) +double_zer_test = zer_test % ('double', DEFAULT_CCONV) #overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) OK else _OVF() #note: XXX this hardcoded int32 minint value is used because of a pre llvm1.6 bug! int_ovf_test = """ - %cond2 = setne INT %x, -2147483648 - br bool %cond2, label %return_block, label %ovf + %%cond2 = setne int %%x, -2147483648 + br bool %%cond2, label %%return_block, label %%ovf ovf: - call fastcc void %__prepare_OverflowError() + call %(DEFAULT_CCONV)s void %%__prepare_OverflowError() unwind -""" +""" % locals() #binary with ZeroDivisionError only for func_inst in "floordiv_zer:div mod_zer:rem".split(): func, inst = func_inst.split(':') - for prefix_type_ in "int:INT uint:UINT".split(): + for prefix_type_ in "int:int uint:uint".split(): prefix, type_ = prefix_type_.split(':') - type_zer_test = zer_test % type_ + type_zer_test = zer_test % (type_, DEFAULT_CCONV) extfunctions["%%%(prefix)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ -internal fastcc %(type_)s %%%(prefix)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s %(type_)s %%%(prefix)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { %(type_zer_test)s %%z = %(inst)s %(type_)s %%x, %%y ret %(type_)s %%z @@ -160,26 +163,26 @@ #unary with OverflowError only extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc INT %%int_neg_ovf(INT %%x) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_neg_ovf(int %%x) { block1: - %%x2 = sub INT 0, %%x + %%x2 = sub int 0, %%x %(int_ovf_test)s return_block: - ret INT %%x2 + ret int %%x2 } """ % locals()) extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc INT %%int_abs_ovf(INT %%x) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_abs_ovf(int %%x) { block0: - %%cond1 = setge INT %%x, 0 + %%cond1 = setge int %%x, 0 br bool %%cond1, label %%return_block, label %%block1 block1: - %%x2 = sub INT 0, %%x + %%x2 = sub int 0, %%x %(int_ovf_test)s return_block: - %%result = phi INT [%%x, %%block0], [%%x2, %%block1] - ret INT %%result + %%result = phi int [%%x, %%block0], [%%x2, %%block1] + ret int %%result } """ % locals()) @@ -187,32 +190,32 @@ #binary with OverflowError only extfunctions["%int_add_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc INT %%int_add_ovf(INT %%x, INT %%y) { - %%t = add INT %%x, %%y +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_add_ovf(int %%x, int %%y) { + %%t = add int %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_add_ovf checking - ret INT %%t + ret int %%t } """ % locals()) extfunctions["%int_sub_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc INT %%int_sub_ovf(INT %%x, INT %%y) { - %%t = sub INT %%x, %%y +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_sub_ovf(int %%x, int %%y) { + %%t = sub int %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_sub_ovf checking - ret INT %%t + ret int %%t } """ % locals()) extfunctions["%int_mul_ovf"] = (("%__prepare_OverflowError",), """ -internal fastcc INT %%int_mul_ovf(INT %%x, INT %%y) { - %%t = mul INT %%x, %%y +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_mul_ovf(int %%x, int %%y) { + %%t = mul int %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_mul_ovf checking - ret INT %%t + ret int %%t } """ % locals()) @@ -220,13 +223,13 @@ #binary with OverflowError and ValueError extfunctions["%int_lshift_ovf_val"] = (("%__prepare_OverflowError","%__prepare_ValueError"), """ -internal fastcc INT %%int_lshift_ovf_val(INT %%x, INT %%y) { - %%yu = cast INT %%y to ubyte - %%t = shl INT %%x, ubyte %%yu +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_lshift_ovf_val(int %%x, int %%y) { + %%yu = cast int %%y to ubyte + %%t = shl int %%x, ubyte %%yu %(int_ovf_test)s return_block: ; XXX: TODO int_lshift_ovf_val checking VAL - ret INT %%t + ret int %%t } """ % locals()) @@ -234,62 +237,62 @@ #binary with OverflowError and ZeroDivisionError extfunctions["%int_floordiv_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ -internal fastcc INT %%int_floordiv_ovf_zer(INT %%x, INT %%y) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_floordiv_ovf_zer(int %%x, int %%y) { %(int_zer_test)s - %%t = div INT %%x, %%y + %%t = div int %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_floordiv_ovf_zer checking - ret INT %%t + ret int %%t } """ % locals()) extfunctions["%int_mod_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ -internal fastcc INT %%int_mod_ovf_zer(INT %%x, INT %%y) { +%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_mod_ovf_zer(int %%x, int %%y) { %(int_zer_test)s - %%t = rem INT %%x, %%y + %%t = rem int %%x, %%y %(int_ovf_test)s return_block: ; XXX: TEST int_mod_ovf_zer checking - ret INT %%t + ret int %%t } """ % locals()) extfunctions["%main"] = (("%string_to_RPyString"), """ -INT %main(INT %argc, sbyte** %argv) { +int %%main(int %%argc, sbyte** %%argv) { entry: - %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(INT 0) - br label %no_exit + %%pypy_argv = call %(DEFAULT_CCONV)s %%RPyListOfString* %%ll_newlist__listPtrConst_Signed.2(int 0) + br label %%no_exit no_exit: - %indvar = phi UINT [ %indvar.next, %next_arg ], [ 0, %entry ] - %i.0.0 = cast UINT %indvar to INT - %tmp.8 = getelementptr sbyte** %argv, UINT %indvar - %tmp.9 = load sbyte** %tmp.8 - - %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 - %res = call ccc INT %strcmp(sbyte* %tmp.9, sbyte* %t) - %cond = seteq INT %res, 0 - br bool %cond, label %debugging, label %not_debugging + %%indvar = phi uint [ %%indvar.next, %%next_arg ], [ 0, %%entry ] + %%i.0.0 = cast uint %%indvar to int + %%tmp.8 = getelementptr sbyte** %%argv, uint %%indvar + %%tmp.9 = load sbyte** %%tmp.8 + + %%t = getelementptr [19 x sbyte]* %%__print_debug_info_option, int 0, int 0 + %%res = call ccc int %%strcmp(sbyte* %%tmp.9, sbyte* %%t) + %%cond = seteq int %%res, 0 + br bool %%cond, label %%debugging, label %%not_debugging debugging: - store bool true, bool* %__print_debug_info - br label %next_arg + store bool true, bool* %%__print_debug_info + br label %%next_arg not_debugging: - %rpy = call fastcc %RPyString* %string_to_RPyString(sbyte* %tmp.9) - call fastcc void %ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) - br label %next_arg + %%rpy = call %(DEFAULT_CCONV)s %%RPyString* %%string_to_RPyString(sbyte* %%tmp.9) + call %(DEFAULT_CCONV)s void %%ll_append__listPtr_rpy_stringPtr(%%RPyListOfString* %%pypy_argv, %%RPyString* %%rpy) + br label %%next_arg next_arg: - %inc = add INT %i.0.0, 1 - %tmp.2 = setlt INT %inc, %argc - %indvar.next = add UINT %indvar, 1 - br bool %tmp.2, label %no_exit, label %loopexit + %%inc = add int %%i.0.0, 1 + %%tmp.2 = setlt int %%inc, %%argc + %%indvar.next = add uint %%indvar, 1 + br bool %%tmp.2, label %%no_exit, label %%loopexit loopexit: - %ret = call fastcc INT %entry_point(%structtype.list* %pypy_argv) - ret INT %ret + %%ret = call %(DEFAULT_CCONV)s int %%entry_point(%%structtype.list* %%pypy_argv) + ret int %%ret } -""") +""" % locals()) From arigo at codespeak.net Thu Aug 25 15:15:19 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 15:15:19 +0200 (CEST) Subject: [pypy-svn] r16490 - pypy/dist/pypy/rpython Message-ID: <20050825131519.7536527B4B@code1.codespeak.net> Author: arigo Date: Thu Aug 25 15:15:17 2005 New Revision: 16490 Modified: pypy/dist/pypy/rpython/rconstantdict.py pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rstr.py Log: Each rtype_method_*() is called by a 'simple_call' operation. This means that we need to declare the possible exceptions, or (as is often the case) that the method doesn't raise an exception. Modified: pypy/dist/pypy/rpython/rconstantdict.py ============================================================================== --- pypy/dist/pypy/rpython/rconstantdict.py (original) +++ pypy/dist/pypy/rpython/rconstantdict.py Thu Aug 25 15:15:17 2005 @@ -90,6 +90,7 @@ self.value_repr) hashcompute = self.get_key_hash_function() chashcompute = hop.inputconst(lltype.Void, hashcompute) + hop.exception_cannot_occur() return hop.gendirectcall(ll_constantdict_get, v_dict, v_key, v_default, chashcompute) Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Thu Aug 25 15:15:17 2005 @@ -111,14 +111,17 @@ def rtype_method_get(self, hop): v_dict, v_key, v_default = hop.inputargs(self, rstr.string_repr, self.value_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_get, v_dict, v_key, v_default) def rtype_method_copy(self, hop): v_dict, = hop.inputargs(self) + hop.exception_cannot_occur() return hop.gendirectcall(ll_copy, v_dict) def rtype_method_update(self, hop): v_dic1, v_dic2 = hop.inputargs(self, self) + hop.exception_cannot_occur() return hop.gendirectcall(ll_update, v_dic1, v_dic2) def _rtype_method_kvi(self, hop, spec): @@ -126,6 +129,7 @@ r_list = hop.r_result v_func = hop.inputconst(lltype.Void, spec) c1 = hop.inputconst(lltype.Void, r_list.lowleveltype) + hop.exception_cannot_occur() return hop.gendirectcall(ll_kvi, v_dic, c1, v_func) def rtype_method_keys(self, hop): Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Thu Aug 25 15:15:17 2005 @@ -123,14 +123,17 @@ llfn = ll_insert_nonneg else: llfn = ll_insert + hop.exception_cannot_occur() hop.gendirectcall(llfn, *args) def rtype_method_extend(self, hop): v_lst1, v_lst2 = hop.inputargs(self, self) + hop.exception_cannot_occur() hop.gendirectcall(ll_extend, v_lst1, v_lst2) def rtype_method_reverse(self, hop): v_lst, = hop.inputargs(self) + hop.exception_cannot_occur() hop.gendirectcall(ll_reverse,v_lst) def rtype_method_pop(self, hop): @@ -148,6 +151,7 @@ else: args = hop.inputargs(self) llfn = ll_pop_default + hop.exception_cannot_occur() # no IndexError support (yet?) return hop.gendirectcall(llfn, *args) def make_iterator_repr(self): Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Thu Aug 25 15:15:17 2005 @@ -101,10 +101,12 @@ def rtype_method_startswith(_, hop): v_str, v_value = hop.inputargs(string_repr, string_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_startswith, v_str, v_value) def rtype_method_endswith(_, hop): v_str, v_value = hop.inputargs(string_repr, string_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_endswith, v_str, v_value) def rtype_method_find(_, hop, reverse=False): @@ -126,6 +128,7 @@ llfn = ll_rfind else: llfn = ll_find + hop.exception_cannot_occur() return hop.gendirectcall(llfn, v_str, v_value, v_start, v_end) def rtype_method_rfind(self, hop): @@ -133,13 +136,16 @@ def rtype_method_upper(_, hop): v_str, = hop.inputargs(string_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_upper, v_str) def rtype_method_lower(_, hop): v_str, = hop.inputargs(string_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_lower, v_str) def rtype_method_join(_, hop): + hop.exception_cannot_occur() if hop.s_result.is_constant(): return inputconst(string_repr, hop.s_result.const) r_lst = hop.args_r[1] @@ -168,12 +174,14 @@ def rtype_method_split(_, hop): v_str, v_chr = hop.inputargs(string_repr, char_repr) c = hop.inputconst(Void, hop.r_result.lowleveltype) + hop.exception_cannot_occur() return hop.gendirectcall(ll_split_chr, c, v_str, v_chr) def rtype_method_replace(_, hop): if not (hop.args_r[1] == char_repr and hop.args_r[2] == char_repr): raise TyperError, 'replace only works for char args' v_str, v_c1, v_c2 = hop.inputargs(string_repr, char_repr, char_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_replace_chr_chr, v_str, v_c1, v_c2) def rtype_int(_, hop): @@ -394,6 +402,7 @@ def rtype_method_isspace(_, hop): vlist = hop.inputargs(char_repr) + hop.exception_cannot_occur() return hop.gendirectcall(ll_char_isspace, vlist[0]) class __extend__(pairtype(CharRepr, IntegerRepr)): From cfbolz at codespeak.net Thu Aug 25 15:18:28 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 15:18:28 +0200 (CEST) Subject: [pypy-svn] r16491 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050825131828.D548827B41@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 15:18:27 2005 New Revision: 16491 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: fixed bug: the roots were never changed. ouch. the copying collector now seems to work reasonably except for the fact that the heapsize is never increased. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Aug 25 15:18:27 2005 @@ -129,6 +129,9 @@ totalsize = size + self.size_gc_header() if self.free + totalsize > self.top_of_space: self.collect() + #XXX need to increase the space size if the object is too big + #for bonus points do big blocks differently + return self.malloc(typeid, length) result = self.free self.init_gc_object(result, typeid) print "mallocing %s, size %s at %s" % (typeid, size, result) @@ -156,8 +159,9 @@ def copy(self, obj): if not self.fromspace <= obj < self.fromspace + self.space_size: return self.copy_non_managed_obj(obj) - print "copying regularly", obj + print "copying regularly", obj, if self.is_forwared(obj): + print "already copied to", self.get_forwarding_address(obj) return self.get_forwarding_address(obj) else: newaddr = self.free @@ -165,11 +169,12 @@ raw_memcopy(obj - self.size_gc_header(), newaddr, totalsize) self.free += totalsize newobj = newaddr + self.size_gc_header() + print "to", newobj self.set_forwarding_address(obj, newobj) return newobj def copy_non_managed_obj(self, obj): #umph, PBCs, not really copy - print "copying nonmanaged", obj + print "copying nonmanaged", obj, self.objectmodel.types[obj.signed[-1]] #we have to do the tracing here because PBCs are not moved to tospace self.trace_and_copy(obj) return obj @@ -197,14 +202,14 @@ pointer.address[0] = self.copy(pointer.address[0]) def is_forwared(self, obj): - return (obj - self.size_gc_header()).signed[1] == -1 + return (obj - self.size_gc_header()).signed[1] < 0 def get_forwarding_address(self, obj): return (obj - self.size_gc_header()).address[0] def set_forwarding_address(self, obj, newobj): gc_info = obj - self.size_gc_header() - gc_info.signed[1] = -1 + gc_info.signed[1] = -gc_info.signed[1] - 1 gc_info.address[0] = newobj def get_size(self, obj): Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Thu Aug 25 15:18:27 2005 @@ -115,6 +115,6 @@ def malloc(self, TYPE, size=0): typeid = self.objectmodel.get_typeid(TYPE) address = self.gc.malloc(typeid, size) - return lltypesimulation.init_object_on_address(address, TYPE, size) + result = lltypesimulation.init_object_on_address(address, TYPE, size) self.objectmodel.update_changed_addresses() return result Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Thu Aug 25 15:18:27 2005 @@ -136,7 +136,7 @@ res = interpret(append_to_list, [i, i - 1]) assert res == i - 1 # crashes if constants are not considered roots - def test_string_concatenation(self): + def DONOTtest_string_concatenation(self): curr = simulator.current_size def concat(j): lst = [] @@ -230,3 +230,25 @@ res = interpret(malloc_a_lot, []) assert simulator.current_size - curr < 16000 print "size before: %s, size after %s" % (curr, simulator.current_size) + + def test_global_list(self): + lst = [] + def append_to_list(i, j): + lst.append([i] * 50) + return lst[j][0] + res = interpret(append_to_list, [0, 0]) + assert res == 0 + for i in range(1, 15): + res = interpret(append_to_list, [i, i - 1]) + assert res == i - 1 # crashes if constants are not considered roots + + def test_string_concatenation(self): + curr = simulator.current_size + def concat(j): + lst = [] + for i in range(j): + lst.append(str(i)) + return len("".join(lst)) + res = interpret(concat, [100]) + assert res == concat(100) + assert simulator.current_size - curr < 16000 From hpk at codespeak.net Thu Aug 25 15:44:55 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 15:44:55 +0200 (CEST) Subject: [pypy-svn] r16493 - in pypy/dist/pypy/interpreter: stablecompiler test Message-ID: <20050825134455.560C527B41@code1.codespeak.net> Author: hpk Date: Thu Aug 25 15:44:54 2005 New Revision: 16493 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/symbols.py pypy/dist/pypy/interpreter/test/test_compiler.py Log: (hpk, pedronis) make a few more scope-related problems vanish (see added tests). Next is to try to tackle the last remaining problems of test_scope.py. Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Thu Aug 25 15:44:54 2005 @@ -266,6 +266,11 @@ self._nameOp('STORE', name) def loadName(self, name): + if (self.scope.nested and not self.scope.localsfullyknown and + name in self.scope.hasbeenfree): + raise SyntaxError("cannot reference variable '%s' because " + "of ambiguity between " + "scopes" % name) self._nameOp('LOAD', name) def delName(self, name): Modified: pypy/dist/pypy/interpreter/stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/symbols.py Thu Aug 25 15:44:54 2005 @@ -22,6 +22,7 @@ self.globals = {} self.params = {} self.frees = {} + self.hasbeenfree = {} self.cells = {} self.children = [] # nested is true if the class could contain free variables, @@ -113,6 +114,7 @@ if not (self.defs.has_key(name) or self.globals.has_key(name)): free[name] = 1 + self.hasbeenfree.update(free) return free.keys() def handle_children(self): Modified: pypy/dist/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_compiler.py (original) +++ pypy/dist/pypy/interpreter/test/test_compiler.py Thu Aug 25 15:44:54 2005 @@ -3,6 +3,7 @@ import py from pypy.interpreter.pycompiler import CPythonCompiler, PythonCompiler from pypy.interpreter.pycode import PyCode +from pypy.interpreter.error import OperationError class BaseTestCompiler: @@ -64,6 +65,57 @@ w_a = space.getitem(w_globals, space.wrap('a')) assert space.int_w(w_a) == 1 + def test_scope_unoptimized_clash1(self): + # mostly taken from test_scope.py + e = py.test.raises(OperationError, self.compiler.compile, """if 1: + def unoptimized_clash1(strip): + def f(s): + from string import * + return strip(s) # ambiguity: free or local + return f""", '', 'exec', 0) + ex = e.value + assert ex.match(self.space, self.space.w_SyntaxError) + + def test_scope_unoptimized_clash1_b(self): + # mostly taken from test_scope.py + e = py.test.raises(OperationError, self.compiler.compile, """if 1: + def unoptimized_clash1(strip): + def f(): + from string import * + return s # ambiguity: free or local + return f""", '', 'exec', 0) + ex = e.value + assert ex.match(self.space, self.space.w_SyntaxError) + + def test_scope_exec_in_nested(self): + e = py.test.raises(OperationError, self.compiler.compile, """if 1: + def unoptimized_clash1(x): + def f(): + exec "z=3" + return x + return f""", '', 'exec', 0) + ex = e.value + assert ex.match(self.space, self.space.w_SyntaxError) + + def test_scope_importstar_in_nested(self): + e = py.test.raises(OperationError, self.compiler.compile, """if 1: + def unoptimized_clash1(x): + def f(): + from string import * + return x + return f""", '', 'exec', 0) + ex = e.value + assert ex.match(self.space, self.space.w_SyntaxError) + + def XXXtest_scope_importstar_with_nested_free(self): + e = py.test.raises(OperationError, self.compiler.compile, """if 1: + def clash(x): + from string import * + def f(s): + return strip(s) + return f""", '', 'exec', 0) + ex = e.value + assert ex.match(self.space, self.space.w_SyntaxError) class TestECCompiler(BaseTestCompiler): def setup_method(self, method): From arigo at codespeak.net Thu Aug 25 16:04:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 16:04:43 +0200 (CEST) Subject: [pypy-svn] r16494 - pypy/dist/pypy/interpreter/test Message-ID: <20050825140443.DD23327B48@code1.codespeak.net> Author: arigo Date: Thu Aug 25 16:04:41 2005 New Revision: 16494 Added: pypy/dist/pypy/interpreter/test/inprogress_test_syntax.py (contents, props changed) Log: A nasty test checking that some constructions are explicitely forbidden by the compiler. (Doesn't work for now.) Added: pypy/dist/pypy/interpreter/test/inprogress_test_syntax.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/interpreter/test/inprogress_test_syntax.py Thu Aug 25 16:04:41 2005 @@ -0,0 +1,265 @@ +import py + +def splitcases(s): + lines = [line.rstrip() for line in s.split('\n')] + s = '\n'.join(lines) + result = [] + for case in s.split('\n\n'): + if case.strip(): + result.append(str(py.code.Source(case))+'\n') + return result + + +VALID = splitcases(""" + + def f(): + def g(): + global x + exec "hi" + x + + def f(): + def g(): + global x + from a import * + x + + def f(x): + def g(): + global x + exec "hi" + x + + def f(x): + def g(): + global x + from a import * + x + + def f(): + def g(): + from a import * + + def f(): + def g(): + exec "hi" + + def f(): + from a import * + + def f(): + exec "hi" + + def f(): + from a import * + def g(): + global x + x + + def f(): + exec "hi" + def g(): + global x + x + + def f(): + from a import * + def g(x): + x + + def f(): + exec "hi" + def g(x): + x + + def f(): + from a import * + lambda x: x + + def f(): + exec "hi" + lambda x: x + + def f(): + from a import * + x + + def f(): + exec "hi" + x + + def f(): + from a import * + (i for i in x) + + def f(): + exec "hi" + (i for i in x) + + def f(): + class g: + exec "hi" + x + + def f(x): + class g: + exec "hi" + x + + def f(): + class g: + from a import * + x + + def f(x): + class g: + from a import * + x + +""") + + +INVALID = splitcases(""" + + def f(): + def g(): + exec "hi" + x + + def f(x): + def g(): + exec "hi" + x + + def f(): + def g(): + from a import * + x + + def f(x): + def g(): + from a import * + x + + def f(): + exec "hi" + def g(): + x + + def f(): + exec "hi" + lambda x: y + + def f(): + from a import * + def g(): + x + + def f(): + from a import * + lambda x: y + + def f(): + exec "hi" + class g: + x + + def f(): + from a import * + class g: + x + + def f(): + exec "hi" + class g: + def h(): + x + + def f(): + from a import * + class g: + def h(): + x + + def f(x): + exec "hi" + class g: + x + + def f(x): + from a import * + class g: + x + + def f(x): + exec "hi" + class g: + def h(): + x + + def f(x): + from a import * + class g: + def h(): + x + + def f(): + (i for i in x) = 10 + +""") + + +for i in range(len(VALID)): + exec """def test_valid_%d(space): + checkvalid(space, %r) +""" % (i, VALID[i]) + +for i in range(len(INVALID)): + exec """def test_invalid_%d(space): + checkinvalid(space, %r) +""" % (i, INVALID[i]) + + +def checkvalid(space, s): + try: + space.call_function(space.builtin.get('compile'), + space.wrap(s), + space.wrap('?'), + space.wrap('exec')) + except: + print '\n' + s + raise + +def checkinvalid(space, s): + from pypy.interpreter.error import OperationError + try: + try: + space.call_function(space.builtin.get('compile'), + space.wrap(s), + space.wrap('?'), + space.wrap('exec')) + except OperationError, e: + if not e.match(space, space.w_SyntaxError): + raise + else: + raise Exception("Should have raised SyntaxError") + except: + print '\n' + s + raise + + +if __name__ == '__main__': + # only to check on top of CPython (you need 2.4) + from py.test import raises + for s in VALID: + try: + compile(s, '?', 'exec') + except: + print s + raise + for s in INVALID: + try: + raises(SyntaxError, compile, s, '?', 'exec') + except: + print s + raise From arigo at codespeak.net Thu Aug 25 16:07:15 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 16:07:15 +0200 (CEST) Subject: [pypy-svn] r16495 - pypy/dist/pypy/rpython Message-ID: <20050825140715.3FF2527B48@code1.codespeak.net> Author: arigo Date: Thu Aug 25 16:07:14 2005 New Revision: 16495 Modified: pypy/dist/pypy/rpython/rstr.py Log: Decidedly missing some hop.exception_cannot_occur(); the general rule is that it is needed in the rtype_*() implementation of any operation that the flow space and the annotator think can raise an exception, but the rtyper knows that it cannot. (Here, the string '%'.) Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Thu Aug 25 16:07:14 2005 @@ -361,6 +361,7 @@ i = inputconst(Signed, i) hop.genop('setarrayitem', [vtemp, i, vchunk]) + hop.exception_cannot_occur() # to ignore the ZeroDivisionError of '%' return hop.gendirectcall(ll_join_strs, vtemp) From rxe at codespeak.net Thu Aug 25 16:09:20 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 16:09:20 +0200 (CEST) Subject: [pypy-svn] r16496 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050825140920.8D82E27B48@code1.codespeak.net> Author: rxe Date: Thu Aug 25 16:09:14 2005 New Revision: 16496 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: Added the rest of math functions - but we have conflicts between checkins...resolving. (ericvrp/rxe) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 16:09:14 2005 @@ -41,6 +41,7 @@ ll_lines = [] funcnames = { "%ll_frexp_result__Float_Signed" : True, + "%ll_modf_result__Float_Float" : True, "%prepare_and_raise_ZeroDivisionError" : True, "%prepare_and_raise_OverflowError" : True, "%prepare_and_raise_ValueError" : True, @@ -177,7 +178,14 @@ j = os.path.join p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") - return get_ll(open(p).read(), extern_dir, ['ll_math_frexp', 'll_math_is_error']) + math_fns = 'acos asin atan ceil cos cosh exp fabs floor log log10 atan2 fmod ' + math_fns += 'sin sinh sqrt tan tanh frexp modf pow hypot ldexp is_error' + #XXX + fns2 = [x[1:] for x in extfuncnode.ExternalFuncNode.used_external_functions.keys()] + fns = ["ll_math_is_error"] + fns += [('ll_math_%s' % f) for f in math_fns.split() if f in fns2] + + return get_ll(open(p).read(), extern_dir, fns) def gen_llvm_source(self, func=None): if self.debug: print 'gen_llvm_source begin) ' + time.ctime() @@ -201,8 +209,6 @@ extern_decls = self.post_setup_externs() self.translator.rtyper.specialize_more_blocks() self.db.setup_all() - - self.generate_llfile(extern_decls) #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) @@ -314,6 +320,11 @@ entryfunc_name = t[1].split('(')[0] if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy extfuncnode.ExternalFuncNode.used_external_functions['%main'] = True + extfuncnode.ExternalFuncNode.used_external_functions['%prepare_and_raise_OverflowError'] = True + extfuncnode.ExternalFuncNode.used_external_functions['%prepare_and_raise_ValueError'] = True + extfuncnode.ExternalFuncNode.used_external_functions['%prepare_and_raise_ZeroDivisionError'] = True + + self.generate_llfile(extern_decls) if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() depdone = {} @@ -341,7 +352,7 @@ filename, really_compile=True, standalone=False, - optimize=True, + optimize=False, exe_name=None): if not llvm_is_on_path(): Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 25 16:09:14 2005 @@ -41,9 +41,9 @@ extfunctions = {} #dependencies, llvm-code -import support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod +import support, ll_os, ll_os_path, ll_time, ll_strtod -for module in (support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod): +for module in (support, ll_os, ll_os_path, ll_time, ll_strtod): extdeclarations += module.extdeclarations extfunctions.update(module.extfunctions) extdeclarations += '\n;application function prototypes' Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 16:09:14 2005 @@ -17,6 +17,7 @@ void prepare_and_raise_OverflowError(char *); void prepare_and_raise_ValueError(char *); + int ll_math_is_error(double x) { if (errno == ERANGE) { if (!x) Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Thu Aug 25 16:09:14 2005 @@ -1,84 +0,0 @@ -extdeclarations = """ -;ll_math.py -declare ccc double %acos(double) -declare ccc double %asin(double) -declare ccc double %atan(double) -declare ccc double %ceil(double) -declare ccc double %cos(double) -declare ccc double %cosh(double) -declare ccc double %exp(double) -declare ccc double %fabs(double) -declare ccc double %floor(double) -declare ccc double %log(double) -declare ccc double %log10(double) -declare ccc double %sin(double) -declare ccc double %sinh(double) -declare ccc double %sqrt(double) -declare ccc double %tan(double) -declare ccc double %tanh(double) -declare ccc double %atan2(double,double) -declare ccc double %fmod(double,double) - -%__ll_math_frexp = constant [12 x sbyte] c"frexp......\\00" -%__ll_math_hypot = constant [12 x sbyte] c"hypot......\\00" -%__ll_math_ldexp = constant [12 x sbyte] c"ldexp......\\00" -%__ll_math_modf = constant [12 x sbyte] c"modf.......\\00" -%__ll_math_pow = constant [12 x sbyte] c"pow........\\00" -""" - -extfunctions = {} - -#functions with a one-to-one C equivalent -simple_functions = [ - ('double %x', ['acos','asin','atan','ceil','cos','cosh','exp','fabs', - 'floor','log','log10','sin','sinh','sqrt','tan','tanh']), - ('double %x, double %y', ['atan2','fmod']), - ] - -simple_function_template = """ -ccc double %%ll_math_%(function)s(%(params)s) { - %%t = call ccc double %%%(function)s(%(params)s) - ret double %%t -} - -""" - -for params, functions in simple_functions: - for function in functions: - extfunctions["%ll_math_" + function] = ((), simple_function_template % locals()) - -extfunctions["%ll_math_hypot"] = (("%__debug",), """ -ccc double %ll_math_hypot(double %x, double %y) { - call ccc void %__debug([12 x sbyte]* %__ll_math_hypot) ; XXX: TODO: ll_math_hypot - ret double 0.0 -} -""") - -extfunctions["%ll_math_ldexp"] = (("%__debug",), """ -ccc double %ll_math_ldexp(double %x, int %y) { - call ccc void %__debug([12 x sbyte]* %__ll_math_ldexp) ; XXX: TODO: ll_math_ldexp - ret double 0.0 -} -""") - -extfunctions["%ll_math_modf"] = (("%__debug",), """ -ccc %RPyMODF_RESULT* %ll_math_modf(double %x) { - call ccc void %__debug([12 x sbyte]* %__ll_math_modf) ; XXX: TODO: ll_math_modf - ret %RPyMODF_RESULT* null -} -""") - -extfunctions["%ll_math_pow"] = (("%__debug",), """ -ccc double %ll_math_pow(double %x, double %y) { - call ccc void %__debug([12 x sbyte]* %__ll_math_pow) ; XXX: TODO: ll_math_pow - ret double 0.0 -} -""") -#;;;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - - -extfunctions["%ll_math_frexp"] = (("%prepare_and_raise_OverflowError", - "%prepare_and_raise_ValueError"), """ -""") - - Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Thu Aug 25 16:09:14 2005 @@ -156,12 +156,12 @@ assert res == fn(10.123) def test_math_modf(): - py.test.skip("ll_math_modf not implemented (next)") from math import modf def fn(x): - return modf(x) + res = modf(x) + return res[0] + res[1] f = compile_function(fn, [float]) - assert f(10.123) == modf(10.123) + assert f(10.123) == fn(10.123) simple_math_functions = [ 'acos', 'asin', 'atan', 'ceil', 'cos', 'cosh', 'exp', 'fabs', From arigo at codespeak.net Thu Aug 25 16:09:57 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 16:09:57 +0200 (CEST) Subject: [pypy-svn] r16497 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050825140957.E449A27B48@code1.codespeak.net> Author: arigo Date: Thu Aug 25 16:09:56 2005 New Revision: 16497 Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py Log: Use the SyntaxError message "invalid syntax" instead of just "error". Gives more compliant tracebacks... Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonparse.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonparse.py Thu Aug 25 16:09:56 2005 @@ -48,7 +48,7 @@ if not result: line, lineno = src.debug() # XXX needs better error messages - raise ParseError("error", lineno, -1, line) + raise ParseError("invalid syntax", lineno, -1, line) # return None return builder From nik at codespeak.net Thu Aug 25 16:21:38 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 16:21:38 +0200 (CEST) Subject: [pypy-svn] r16498 - pypy/dist/pypy/module/_sre Message-ID: <20050825142138.4D93027B48@code1.codespeak.net> Author: nik Date: Thu Aug 25 16:21:37 2005 New Revision: 16498 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: some refactorings to clear up confusion about which objects are wrapped and which are not. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 16:21:37 2005 @@ -369,6 +369,10 @@ string_position += 1 return False +# XXX temporary constants for MatchContext.has_matched +UNDECIDED = 0 +MATCHED = 1 +NOT_MATCHED = 2 def match(state, pattern_codes): # Optimization: Check string length. pattern_codes[3] contains the @@ -381,13 +385,13 @@ dispatcher = _OpcodeDispatcher() state.context_stack.append(_sre._MatchContext(state, pattern_codes)) - has_matched = None + has_matched = UNDECIDED while len(state.context_stack) > 0: context = state.context_stack[-1] has_matched = dispatcher.match(context) - if has_matched is not None: # don't pop if context isn't done + if has_matched != UNDECIDED: # don't pop if context isn't done state.context_stack.pop() - return has_matched + return has_matched == MATCHED class _Dispatcher(object): @@ -422,12 +426,12 @@ """Returns True if the current context matches, False if it doesn't and None if matching is not finished, ie must be resumed after child contexts have been matched.""" - while context.remaining_codes() > 0 and context.has_matched is None: + while context.remaining_codes() > 0 and context.has_matched == UNDECIDED: opcode = context.peek_code() if not self.dispatch(opcode, context): - return None - if context.has_matched is None: - context.has_matched = False + return UNDECIDED + if context.has_matched == UNDECIDED: + context.has_matched = NOT_MATCHED return context.has_matched def dispatch(self, opcode, context): @@ -453,7 +457,7 @@ def general_op_literal(self, ctx, compare, decorate=lambda x: x): if ctx.at_end() or not compare(decorate(ord(ctx.peek_char())), decorate(ctx.peek_code(1))): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED ctx.skip_code(2) ctx.skip_char(1) @@ -491,7 +495,7 @@ #self._log(ctx, "AT", ctx.peek_code(1)) if not _sre._at_dispatch(ctx.peek_code(1), ctx.state.string, ctx.string_position, ctx.state.end): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return True ctx.skip_code(2) return True @@ -502,7 +506,7 @@ #self._log(ctx, "CATEGORY", ctx.peek_code(1)) if ctx.at_end() or \ not _sre._category_dispatch(ctx.peek_code(1), ctx.peek_char()): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return True ctx.skip_code(2) ctx.skip_char(1) @@ -513,7 +517,7 @@ # #self._log(ctx, "ANY") if ctx.at_end() or ctx.at_linebreak(): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return True ctx.skip_code(1) ctx.skip_char(1) @@ -524,7 +528,7 @@ # #self._log(ctx, "ANY_ALL") if ctx.at_end(): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return True ctx.skip_code(1) ctx.skip_char(1) @@ -533,14 +537,14 @@ def general_op_in(self, ctx, decorate=lambda x: x): #self._log(ctx, "OP_IN") if ctx.at_end(): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return skip = ctx.peek_code(1) ctx.skip_code(2) # set op pointer to the set code char = decorate(ord(ctx.peek_char())) if not _sre._check_charset(ctx.pattern_codes[ctx.code_position:], char, ctx.state.string, ctx.string_position): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return ctx.skip_code(skip - 1) ctx.skip_char(1) @@ -593,14 +597,14 @@ ctx.state.string_position = ctx.string_position child_context = ctx.push_new_context(1) yield False - if child_context.has_matched: - ctx.has_matched = True + if child_context.has_matched == MATCHED: + ctx.has_matched = MATCHED yield True ctx.state.marks_pop_keep() ctx.skip_code(current_branch_length) current_branch_length = ctx.peek_code(0) ctx.state.marks_pop_discard() - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True def op_repeat_one(self, ctx): @@ -613,18 +617,18 @@ #self._log(ctx, "REPEAT_ONE", mincount, maxcount) if ctx.remaining_chars() < mincount: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True ctx.state.string_position = ctx.string_position count = self.count_repetitions(ctx, maxcount) ctx.skip_char(count) if count < mincount: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: # tail is empty. we're finished ctx.state.string_position = ctx.string_position - ctx.has_matched = True + ctx.has_matched = MATCHED yield True ctx.state.marks_push() @@ -642,8 +646,8 @@ ctx.state.string_position = ctx.string_position child_context = ctx.push_new_context(ctx.peek_code(1) + 1) yield False - if child_context.has_matched: - ctx.has_matched = True + if child_context.has_matched == MATCHED: + ctx.has_matched = MATCHED yield True ctx.skip_char(-1) count -= 1 @@ -655,15 +659,15 @@ ctx.state.string_position = ctx.string_position child_context = ctx.push_new_context(ctx.peek_code(1) + 1) yield False - if child_context.has_matched: - ctx.has_matched = True + if child_context.has_matched == MATCHED: + ctx.has_matched = MATCHED yield True ctx.skip_char(-1) count -= 1 ctx.state.marks_pop_keep() ctx.state.marks_pop_discard() - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True def op_min_repeat_one(self, ctx): @@ -674,7 +678,7 @@ #self._log(ctx, "MIN_REPEAT_ONE", mincount, maxcount) if ctx.remaining_chars() < mincount: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True ctx.state.string_position = ctx.string_position if mincount == 0: @@ -682,13 +686,13 @@ else: count = self.count_repetitions(ctx, mincount) if count < mincount: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True ctx.skip_char(count) if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: # tail is empty. we're finished ctx.state.string_position = ctx.string_position - ctx.has_matched = True + ctx.has_matched = MATCHED yield True ctx.state.marks_push() @@ -696,8 +700,8 @@ ctx.state.string_position = ctx.string_position child_context = ctx.push_new_context(ctx.peek_code(1) + 1) yield False - if child_context.has_matched: - ctx.has_matched = True + if child_context.has_matched == MATCHED: + ctx.has_matched = MATCHED yield True ctx.state.string_position = ctx.string_position if self.count_repetitions(ctx, 1) == 0: @@ -707,7 +711,7 @@ ctx.state.marks_pop_keep() ctx.state.marks_pop_discard() - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True def op_repeat(self, ctx): @@ -742,7 +746,7 @@ child_context = repeat.push_new_context(4) yield False ctx.has_matched = child_context.has_matched - if not ctx.has_matched: + if ctx.has_matched == NOT_MATCHED: repeat.count = count - 1 ctx.state.string_position = ctx.string_position yield True @@ -757,9 +761,9 @@ child_context = repeat.push_new_context(4) yield False repeat.last_position = save_last_position - if child_context.has_matched: + if child_context.has_matched == MATCHED: ctx.state.marks_pop_discard() - ctx.has_matched = True + ctx.has_matched = MATCHED yield True ctx.state.marks_pop() repeat.count = count - 1 @@ -770,7 +774,7 @@ child_context = ctx.push_new_context(1) yield False ctx.has_matched = child_context.has_matched - if not ctx.has_matched: + if ctx.has_matched == NOT_MATCHED: ctx.state.repeat = repeat ctx.state.string_position = ctx.string_position yield True @@ -793,7 +797,7 @@ child_context = repeat.push_new_context(4) yield False ctx.has_matched = child_context.has_matched - if not ctx.has_matched: + if ctx.has_matched == NOT_MATCHED: repeat.count = count - 1 ctx.state.string_position = ctx.string_position yield True @@ -803,8 +807,8 @@ ctx.state.repeat = repeat.previous child_context = ctx.push_new_context(1) yield False - if child_context.has_matched: - ctx.has_matched = True + if child_context.has_matched == MATCHED: + ctx.has_matched = MATCHED yield True ctx.state.repeat = repeat ctx.state.string_position = ctx.string_position @@ -812,13 +816,13 @@ # match more until tail matches if count >= maxcount and maxcount != MAXREPEAT: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True repeat.count = count child_context = repeat.push_new_context(4) yield False ctx.has_matched = child_context.has_matched - if not ctx.has_matched: + if ctx.has_matched == NOT_MATCHED: repeat.count = count - 1 ctx.state.string_position = ctx.string_position yield True @@ -826,12 +830,12 @@ def general_op_groupref(self, ctx, decorate=lambda x: x): group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) if group_start is None or group_end is None or group_end < group_start: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return True while group_start < group_end: if ctx.at_end() or decorate(ord(ctx.peek_char())) \ != decorate(ord(ctx.state.string[group_start])): - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED return True group_start += 1 ctx.skip_char(1) @@ -866,14 +870,14 @@ #self._log(ctx, "ASSERT", ctx.peek_code(2)) ctx.state.string_position = ctx.string_position - ctx.peek_code(2) if ctx.state.string_position < 0: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True child_context = ctx.push_new_context(3) yield False - if child_context.has_matched: + if child_context.has_matched == MATCHED: ctx.skip_code(ctx.peek_code(1) + 1) else: - ctx.has_matched = False + ctx.has_matched = NOT_MATCHED yield True def op_assert_not(self, ctx): @@ -884,8 +888,8 @@ if ctx.state.string_position >= 0: child_context = ctx.push_new_context(3) yield False - if child_context.has_matched: - ctx.has_matched = False + if child_context.has_matched == MATCHED: + ctx.has_matched = NOT_MATCHED yield True ctx.skip_code(ctx.peek_code(1) + 1) yield True @@ -914,10 +918,10 @@ # a success opcode ctx.code_position = reset_position self.dispatch(ctx.peek_code(), ctx) - if ctx.has_matched is False: # could be None as well + if ctx.has_matched == NOT_MATCHED: # could be None as well break count += 1 - ctx.has_matched = None + ctx.has_matched = UNDECIDED ctx.code_position = code_position ctx.string_position = string_position return count Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 16:21:37 2005 @@ -153,62 +153,54 @@ class W_MatchContext(Wrappable): + UNDECIDED = 0 + MATCHED = 1 + NOT_MATCHED = 2 + def __init__(self, space, w_state, w_pattern_codes): self.space = space - self.w_state = w_state + self.state = w_state self.pattern_codes_w = space.unpackiterable(w_pattern_codes) - self.w_string_position = space.wrap(w_state.string_position) - self.w_code_position = space.wrap(0) - self.w_has_matched = space.w_None - - # XXX These attributes are only really used with repeat operations. - # Formerly a subclass of MatchContext was used for these, but for - # simplictiy we simply add them here for now. - #self.count = space.wrap(-1) - #self.previous = context.state.repeat - #self.last_position = None + self.string_position = w_state.string_position + self.code_position = 0 + self.has_matched = self.UNDECIDED def push_new_context(self, w_pattern_offset): """Creates a new child context of this context and pushes it on the stack. pattern_offset is the offset off the current code position to start interpreting from.""" pattern_offset = self.space.int_w(w_pattern_offset) - pattern_codes_w = self.pattern_codes_w[ - self.space.int_w(self.w_code_position) + pattern_offset:] - w_child_context = self.space.wrap(W_MatchContext(self.space, self.w_state, + pattern_codes_w = self.pattern_codes_w[self.code_position + pattern_offset:] + w_child_context = self.space.wrap(W_MatchContext(self.space, self.state, self.space.newlist(pattern_codes_w))) - self.space.call_method(self.w_state.w_context_stack, "append", w_child_context) - #context_stack = self.space.unpackiterable(self.w_state.w_context_stack) - #context_stack.append(w_child_context) + self.space.call_method(self.state.w_context_stack, "append", w_child_context) return w_child_context def peek_char(self, w_peek=0): - return self.space.getitem(self.w_state.w_string, - self.space.add(self.w_string_position, w_peek)) + return self.space.getitem(self.state.w_string, + self.space.add(self.space.wrap(self.string_position), w_peek)) def skip_char(self, w_skip_count): - self.w_string_position = self.space.add(self.w_string_position, w_skip_count) + self.string_position = self.string_position + self.space.int_w(w_skip_count) def remaining_chars(self): - return self.space.sub(self.space.wrap(self.w_state.end), self.w_string_position) + return self.space.wrap(self.state.end - self.string_position) def peek_code(self, w_peek=0): space = self.space - return self.pattern_codes_w[ - space.int_w(space.add(self.w_code_position, w_peek))] + return self.pattern_codes_w[self.code_position + self.space.int_w(w_peek)] def skip_code(self, w_skip_count): - self.w_code_position = self.space.add(self.w_code_position, w_skip_count) + self.code_position = self.code_position + self.space.int_w(w_skip_count) def remaining_codes(self): - return self.space.sub(self.space.wrap(len(self.pattern_codes_w)), - self.w_code_position) + return self.space.wrap(len(self.pattern_codes_w) - self.code_position) def at_beginning(self): - return self.space.eq(self.w_string_position, self.space.wrap(0)) + return self.space.newbool(self.string_position == 0) def at_end(self): - return self.space.eq(self.w_string_position, self.space.wrap(self.w_state.end)) + return self.space.newbool(self.string_position == self.state.end) def at_linebreak(self): space = self.space @@ -216,11 +208,11 @@ space.eq(self.peek_char(space.wrap(0)), space.wrap("\n"))) W_MatchContext.typedef = TypeDef("W_MatchContext", - state = interp_attrproperty_w("w_state", W_MatchContext), - string_position = interp_attrproperty_obj_w("w_string_position", W_MatchContext), + state = interp_attrproperty_w("state", W_MatchContext), + string_position = interp_attrproperty_int("string_position", W_MatchContext), pattern_codes = interp_attrproperty_list_w("pattern_codes_w", W_MatchContext), - code_position = interp_attrproperty_obj_w("w_code_position", W_MatchContext), - has_matched = interp_attrproperty_obj_w("w_has_matched", W_MatchContext), + code_position = interp_attrproperty_int("code_position", W_MatchContext), + has_matched = interp_attrproperty_int("has_matched", W_MatchContext), push_new_context = interp2app(W_MatchContext.push_new_context), peek_char = interp2app(W_MatchContext.peek_char), skip_char = interp2app(W_MatchContext.skip_char), @@ -240,10 +232,10 @@ class W_RepeatContext(W_MatchContext): def __init__(self, space, w_context): - W_MatchContext.__init__(self, space, w_context.w_state, - space.newlist(w_context.pattern_codes_w[space.int_w(w_context.w_code_position):])) + W_MatchContext.__init__(self, space, w_context.state, + space.newlist(w_context.pattern_codes_w[w_context.code_position:])) self.w_count = space.wrap(-1) - self.w_previous = w_context.w_state.w_repeat + self.w_previous = w_context.state.w_repeat self.w_last_position = space.w_None W_RepeatContext.typedef = TypeDef("W_RepeatContext", W_MatchContext.typedef, @@ -264,15 +256,15 @@ opcode = space.int_w(w_opcode) return space.newbool(opcode_dispatch_table[opcode] is not None) -def op_success(space, w_ctx): +def op_success(space, ctx): # end of pattern - w_ctx.w_state.string_position = space.int_w(w_ctx.w_string_position) - w_ctx.w_has_matched = space.newbool(True) + ctx.state.string_position = ctx.string_position + ctx.has_matched = ctx.MATCHED return True -def op_failure(space, w_ctx): +def op_failure(space, ctx): # immediate failure - w_ctx.w_has_matched = space.newbool(False) + ctx.has_matched = ctx.NOT_MATCHED return True opcode_dispatch_table = [ From rxe at codespeak.net Thu Aug 25 16:24:18 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 16:24:18 +0200 (CEST) Subject: [pypy-svn] r16499 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050825142418.4C1E827B48@code1.codespeak.net> Author: rxe Date: Thu Aug 25 16:24:17 2005 New Revision: 16499 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/genllvm.py Log: Make (some) tests run again. Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Thu Aug 25 16:24:17 2005 @@ -77,9 +77,10 @@ cmds = ["llvm-as %s.ll" % b] bcfile = dirpath.join("externs", "externs_linked.bc") - cmds.append("llvm-link %s.bc %s -o %s_all.bc" % (b, str(bcfile), b)) - ball = str(dirpath.join('%s_all.bc' % b)) - cmds.append("opt %s %s -f -o %s.bc" % (OPTIMIZATION_SWITCHES, ball, b)) + if bcfile.check(file=1): + cmds.append("llvm-link %s.bc %s -o %s_all.bc" % (b, str(bcfile), b)) + ball = str(dirpath.join('%s_all.bc' % b)) + cmds.append("opt %s %s -f -o %s.bc" % (OPTIMIZATION_SWITCHES, ball, b)) if False and sys.maxint == 2147483647: #32 bit platform cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 16:24:17 2005 @@ -182,8 +182,10 @@ math_fns += 'sin sinh sqrt tan tanh frexp modf pow hypot ldexp is_error' #XXX fns2 = [x[1:] for x in extfuncnode.ExternalFuncNode.used_external_functions.keys()] - fns = ["ll_math_is_error"] - fns += [('ll_math_%s' % f) for f in math_fns.split() if f in fns2] + + fns = [('ll_math_%s' % f) for f in math_fns.split() if f in fns2] + if fns: + fns.append("ll_math_is_error") return get_ll(open(p).read(), extern_dir, fns) From nik at codespeak.net Thu Aug 25 16:55:22 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 16:55:22 +0200 (CEST) Subject: [pypy-svn] r16501 - pypy/dist/pypy/module/_sre Message-ID: <20050825145522.4BBA027B4B@code1.codespeak.net> Author: nik Date: Thu Aug 25 16:55:21 2005 New Revision: 16501 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved literal opcodes to interp-level. split some methods into a wrapped and a non-wrapped version, this will save time later when we'll want to get rid of all wrapped stuff. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 16:55:21 2005 @@ -461,34 +461,6 @@ ctx.skip_code(2) ctx.skip_char(1) - def op_literal(self, ctx): - # match literal string - # - #self._log(ctx, "LITERAL", ctx.peek_code(1)) - self.general_op_literal(ctx, operator.eq) - return True - - def op_not_literal(self, ctx): - # match anything that is not the given literal character - # - #self._log(ctx, "NOT_LITERAL", ctx.peek_code(1)) - self.general_op_literal(ctx, operator.ne) - return True - - def op_literal_ignore(self, ctx): - # match literal regardless of case - # - #self._log(ctx, "LITERAL_IGNORE", ctx.peek_code(1)) - self.general_op_literal(ctx, operator.eq, ctx.state.lower) - return True - - def op_not_literal_ignore(self, ctx): - # match literal regardless of case - # - #self._log(ctx, "LITERAL_IGNORE", ctx.peek_code(1)) - self.general_op_literal(ctx, operator.ne, ctx.state.lower) - return True - def op_at(self, ctx): # match at given position # Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 16:55:21 2005 @@ -102,7 +102,10 @@ def marks_pop_discard(self): self.marks_stack.pop() - def lower(self, w_char_ord): + def lower(self, char_ord): + return self.space.int_w(self.w_lower(self.space.wrap(char_ord))) + + def w_lower(self, w_char_ord): return getlower(self.space, w_char_ord, self.space.wrap(self.flags)) def interp_attrproperty_int(name, cls): @@ -144,7 +147,7 @@ marks_pop = interp2app(W_State.marks_pop), marks_pop_keep = interp2app(W_State.marks_pop_keep), marks_pop_discard = interp2app(W_State.marks_pop_discard), - lower = interp2app(W_State.lower), + lower = interp2app(W_State.w_lower), ) def make_context(space, w_state, w_pattern_codes): @@ -180,18 +183,29 @@ return self.space.getitem(self.state.w_string, self.space.add(self.space.wrap(self.string_position), w_peek)) - def skip_char(self, w_skip_count): - self.string_position = self.string_position + self.space.int_w(w_skip_count) + def peek_char_ord(self, peek=0): + return self.space.int_w(self.space.ord(self.peek_char(self.space.wrap(peek)))) + + def skip_char(self, skip_count): + self.string_position = self.string_position + skip_count + + def w_skip_char(self, w_skip_count): + self.skip_char(self.space.int_w(w_skip_count)) def remaining_chars(self): return self.space.wrap(self.state.end - self.string_position) - def peek_code(self, w_peek=0): - space = self.space - return self.pattern_codes_w[self.code_position + self.space.int_w(w_peek)] + def peek_code(self, peek=0): + return self.space.int_w(self.pattern_codes_w[self.code_position + peek]) - def skip_code(self, w_skip_count): - self.code_position = self.code_position + self.space.int_w(w_skip_count) + def w_peek_code(self, w_peek=0): + return self.space.wrap(self.peek_code(self.space.int_w(w_peek))) + + def skip_code(self, skip_count): + self.code_position = self.code_position + skip_count + + def w_skip_code(self, w_skip_count): + self.skip_code(self.space.int_w(w_skip_count)) def remaining_codes(self): return self.space.wrap(len(self.pattern_codes_w) - self.code_position) @@ -200,7 +214,10 @@ return self.space.newbool(self.string_position == 0) def at_end(self): - return self.space.newbool(self.string_position == self.state.end) + return self.string_position == self.state.end + + def w_at_end(self): + return self.space.newbool(self.at_end()) def at_linebreak(self): space = self.space @@ -215,13 +232,13 @@ has_matched = interp_attrproperty_int("has_matched", W_MatchContext), push_new_context = interp2app(W_MatchContext.push_new_context), peek_char = interp2app(W_MatchContext.peek_char), - skip_char = interp2app(W_MatchContext.skip_char), + skip_char = interp2app(W_MatchContext.w_skip_char), remaining_chars = interp2app(W_MatchContext.remaining_chars), - peek_code = interp2app(W_MatchContext.peek_code), - skip_code = interp2app(W_MatchContext.skip_code), + peek_code = interp2app(W_MatchContext.w_peek_code), + skip_code = interp2app(W_MatchContext.w_skip_code), remaining_codes = interp2app(W_MatchContext.remaining_codes), at_beginning = interp2app(W_MatchContext.at_beginning), - at_end = interp2app(W_MatchContext.at_end), + at_end = interp2app(W_MatchContext.w_at_end), at_linebreak = interp2app(W_MatchContext.at_linebreak), ) @@ -267,8 +284,46 @@ ctx.has_matched = ctx.NOT_MATCHED return True +def op_literal(space, ctx): + # match literal string + # + if ctx.at_end() or ctx.peek_char_ord() != ctx.peek_code(1): + ctx.has_matched = ctx.NOT_MATCHED + ctx.skip_code(2) + ctx.skip_char(1) + return True + +def op_not_literal(self, ctx): + # match anything that is not the given literal character + # + if ctx.at_end() or ctx.peek_char_ord() == ctx.peek_code(1): + ctx.has_matched = ctx.NOT_MATCHED + ctx.skip_code(2) + ctx.skip_char(1) + return True + +def op_literal_ignore(self, ctx): + # match literal regardless of case + # + if ctx.at_end() or \ + ctx.state.lower(ctx.peek_char_ord()) != ctx.state.lower(ctx.peek_code(1)): + ctx.has_matched = ctx.NOT_MATCHED + ctx.skip_code(2) + ctx.skip_char(1) + return True + +def op_not_literal_ignore(self, ctx): + # match literal regardless of case + # + if ctx.at_end() or \ + ctx.state.lower(ctx.peek_char_ord()) == ctx.state.lower(ctx.peek_code(1)): + ctx.has_matched = ctx.NOT_MATCHED + ctx.skip_code(2) + ctx.skip_char(1) + return True + opcode_dispatch_table = [ - op_failure, op_success, #FAILURE, SUCCESS, + op_failure, op_success, None, None, #ANY, ANY_ALL, None, None, #ASSERT, ASSERT_NOT, None, #AT, @@ -280,11 +335,11 @@ None, None, #IN, IN_IGNORE, None, #INFO, None, #JUMP, - None, None, #LITERAL, LITERAL_IGNORE, + op_literal, op_literal_ignore, None, #MARK, None, #MAX_UNTIL, None, #MIN_UNTIL, - None, None, #NOT_LITERAL, NOT_LITERAL_IGNORE, + op_not_literal, op_not_literal_ignore, None, #NEGATE, None, #RANGE, None, #REPEAT, From ale at codespeak.net Thu Aug 25 17:04:56 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 17:04:56 +0200 (CEST) Subject: [pypy-svn] r16503 - in pypy/dist/pypy: lib module/__builtin__ Message-ID: <20050825150456.8B69227B4B@code1.codespeak.net> Author: ale Date: Thu Aug 25 17:04:52 2005 New Revision: 16503 Modified: pypy/dist/pypy/lib/imp.py pypy/dist/pypy/module/__builtin__/importing.py Log: (arre, ale) Changed the logic .pyc imports Make sure to remove failed imports from sys.modules In imp.py added support for .pyc files Modified: pypy/dist/pypy/lib/imp.py ============================================================================== --- pypy/dist/pypy/lib/imp.py (original) +++ pypy/dist/pypy/lib/imp.py Thu Aug 25 17:04:52 2005 @@ -43,9 +43,9 @@ filename = os.path.join(base, name) if os.path.isdir(filename): return (None, filename, ('', '', PKG_DIRECTORY)) - filename += '.py' - if os.path.exists(filename): - return (file(filename, 'U'), filename, ('.py', 'U', PY_SOURCE)) + for ext, mode, kind in get_suffixes(): + if os.path.exists(filename+ext): + return (file(filename+ext, mode), filename+ext, (ext, mode, kind)) raise ImportError, 'No module named %s' % (name,) @@ -72,11 +72,11 @@ if type == C_BUILTIN: module = __import__(name, {}, {}, None) return module - + if type == PY_COMPILED: + return load_compiled(name, filename, file) raise ValueError, 'invalid description argument: %r' % (description,) def load_source(name, pathname, file=None): - import sys autoopen = file is None if autoopen: file = open(pathname, 'U') @@ -84,15 +84,10 @@ if autoopen: file.close() co = compile(source, pathname, 'exec') - module = sys.modules.setdefault(name, new_module(name)) - module.__name__ = name - module.__doc__ = None - module.__file__ = pathname - exec co in module.__dict__ - return module + return run_module(name, pathname, co) def load_compiled(name, pathname, file=None): - import sys, marshal + import marshal autoopen = file is None if autoopen: file = open(pathname, 'rb') @@ -103,13 +98,21 @@ co = marshal.load(file) if autoopen: file.close() + return run_module(name, pathname, co) + +def run_module(name, pathname, co): + import sys module = sys.modules.setdefault(name, new_module(name)) module.__name__ = name module.__doc__ = None module.__file__ = pathname - exec co in module.__dict__ + try: + exec co in module.__dict__ + except : + sys.module.pop(name,None) + raise return module - + def new_module(name): """Create a new module. Do not enter it in sys.modules. Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Thu Aug 25 17:04:52 2005 @@ -53,7 +53,7 @@ if PYC_ONOFF and os.path.exists(pycfile): pyc_state = check_compiled_module(space, pyfile, pyfile_ts, pycfile) pycfile_exists = pyc_state >= 0 - pycfile_ts_valid = pyc_state > 0 and pyfile_exist + pycfile_ts_valid = pyc_state > 0 or (pyc_state == 0 and not pyfile_exist) else: pycfile_exists = False pycfile_ts_valid = False @@ -121,13 +121,9 @@ osfile.close() except OperationError, e: - if e.match(space, space.w_SyntaxError): - w_mods = space.sys.get('modules') - try: - space.delitem(w_mods, w_modulename) - except OperationError, kerr: - if not kerr.match(space, space.w_KeyError): - raise + w_mods = space.sys.get('modules') + space.call_method(w_mods,'pop', w_modulename, space.w_None) + raise w_mod = check_sys_modules(space, w_modulename) if w_mod is not None and w_parent is not None: From ale at codespeak.net Thu Aug 25 17:09:29 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 17:09:29 +0200 (CEST) Subject: [pypy-svn] r16504 - pypy/dist/pypy/lib Message-ID: <20050825150929.706FF27B4B@code1.codespeak.net> Author: ale Date: Thu Aug 25 17:09:28 2005 New Revision: 16504 Modified: pypy/dist/pypy/lib/imp.py Log: (arre, ale) oups typo Modified: pypy/dist/pypy/lib/imp.py ============================================================================== --- pypy/dist/pypy/lib/imp.py (original) +++ pypy/dist/pypy/lib/imp.py Thu Aug 25 17:09:28 2005 @@ -109,7 +109,7 @@ try: exec co in module.__dict__ except : - sys.module.pop(name,None) + sys.modules.pop(name,None) raise return module From rxe at codespeak.net Thu Aug 25 17:21:58 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 17:21:58 +0200 (CEST) Subject: [pypy-svn] r16505 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050825152158.6363E27B4B@code1.codespeak.net> Author: rxe Date: Thu Aug 25 17:21:55 2005 New Revision: 16505 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/codewriter.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/ll_strtod.py pypy/dist/pypy/translator/llvm2/module/ll_time.py pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_gc.py pypy/dist/pypy/translator/llvm2/varsize.py Log: Reverted back to before -r16488 and enabled all ll_math_xxx tests. No idea what was going on. (ericvrp/rxe) Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Thu Aug 25 17:21:55 2005 @@ -77,10 +77,9 @@ cmds = ["llvm-as %s.ll" % b] bcfile = dirpath.join("externs", "externs_linked.bc") - if bcfile.check(file=1): - cmds.append("llvm-link %s.bc %s -o %s_all.bc" % (b, str(bcfile), b)) - ball = str(dirpath.join('%s_all.bc' % b)) - cmds.append("opt %s %s -f -o %s.bc" % (OPTIMIZATION_SWITCHES, ball, b)) + cmds.append("llvm-link %s.bc %s -o %s_all.bc" % (b, str(bcfile), b)) + ball = str(dirpath.join('%s_all.bc' % b)) + cmds.append("opt %s %s -f -o %s.bc" % (OPTIMIZATION_SWITCHES, ball, b)) if False and sys.maxint == 2147483647: #32 bit platform cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) Modified: pypy/dist/pypy/translator/llvm2/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm2/codewriter.py Thu Aug 25 17:21:55 2005 @@ -4,9 +4,9 @@ log = log.codewriter -DEFAULT_TAIL = '' #/tail -DEFAULT_CCONV = 'ccc' #ccc/fastcc -DEFAULT_INTERNAL = '' #/internal +DEFAULT_TAIL = 'tail' #/tail +DEFAULT_CCONV = 'fastcc' #ccc/fastcc +DEFAULT_INTERNAL = 'internal' #/internal class CodeWriter(object): def __init__(self, f, word, uword, show_line_number=False): @@ -40,7 +40,7 @@ self.append(" %s:" % name) def globalinstance(self, name, typeandata): - self.append("%s = %s global %s" % (name, DEFAULT_INTERNAL, typeandata)) + self.append("%s = %s global %s" % (name, "internal", typeandata)) def structdef(self, name, typereprs): self.append("%s = type { %s }" %(name, ", ".join(typereprs))) @@ -80,7 +80,7 @@ if is_entrynode: linkage_type = '' else: - linkage_type = DEFAULT_INTERNAL + ' ' + linkage_type = ' ' self.append("%s%s %s {" % (linkage_type, cconv, decl,)) def closefunc(self): Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 17:21:55 2005 @@ -55,7 +55,7 @@ returntype, s = line.split(' ', 1) funcname , s = s.split('(', 1) funcnames[funcname] = True - line = '%s %s %s' % (DEFAULT_INTERNAL, DEFAULT_CCONV, line,) + line = '%s %s %s' % ("internal", DEFAULT_CCONV, line,) ll_lines.append(line) #patch calls to function that we just declared fastcc @@ -180,13 +180,7 @@ p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") math_fns = 'acos asin atan ceil cos cosh exp fabs floor log log10 atan2 fmod ' math_fns += 'sin sinh sqrt tan tanh frexp modf pow hypot ldexp is_error' - #XXX - fns2 = [x[1:] for x in extfuncnode.ExternalFuncNode.used_external_functions.keys()] - - fns = [('ll_math_%s' % f) for f in math_fns.split() if f in fns2] - if fns: - fns.append("ll_math_is_error") - + fns = [('ll_math_%s' % f) for f in math_fns.split()] return get_ll(open(p).read(), extern_dir, fns) def gen_llvm_source(self, func=None): @@ -211,6 +205,8 @@ extern_decls = self.post_setup_externs() self.translator.rtyper.specialize_more_blocks() self.db.setup_all() + + self.generate_llfile(extern_decls) #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) @@ -322,11 +318,6 @@ entryfunc_name = t[1].split('(')[0] if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy extfuncnode.ExternalFuncNode.used_external_functions['%main'] = True - extfuncnode.ExternalFuncNode.used_external_functions['%prepare_and_raise_OverflowError'] = True - extfuncnode.ExternalFuncNode.used_external_functions['%prepare_and_raise_ValueError'] = True - extfuncnode.ExternalFuncNode.used_external_functions['%prepare_and_raise_ZeroDivisionError'] = True - - self.generate_llfile(extern_decls) if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() depdone = {} Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 25 17:21:55 2005 @@ -1,49 +1,46 @@ -import py -from pypy.translator.llvm2.codewriter import DEFAULT_INTERNAL, DEFAULT_CCONV - extdeclarations = """;rpython stuff ;gc-type dependent mallocs -declare %(DEFAULT_CCONV)s sbyte* %%gc_malloc(uint) -declare %(DEFAULT_CCONV)s sbyte* %%gc_malloc_atomic(uint) +declare fastcc sbyte* %gc_malloc(uint) +declare fastcc sbyte* %gc_malloc_atomic(uint) ;exception handling globals -%%last_exception_type = global %%RPYTHON_EXCEPTION_VTABLE* null -%%last_exception_value = global %%RPYTHON_EXCEPTION* null -""" % locals() - -gc_boehm = """declare ccc sbyte* %%GC_malloc(uint) -declare ccc sbyte* %%GC_malloc_atomic(uint) - -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc(uint %%n) { - %%ptr = call ccc sbyte* %%GC_malloc(uint %%n) - ret sbyte* %%ptr +%last_exception_type = global %RPYTHON_EXCEPTION_VTABLE* null +%last_exception_value = global %RPYTHON_EXCEPTION* null +""" + +gc_boehm = """declare ccc sbyte* %GC_malloc(uint) +declare ccc sbyte* %GC_malloc_atomic(uint) + +internal fastcc sbyte* %gc_malloc(uint %n) { + %ptr = call ccc sbyte* %GC_malloc(uint %n) + ret sbyte* %ptr } -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc_atomic(uint %%n) { - %%ptr = call ccc sbyte* %%GC_malloc_atomic(uint %%n) - ret sbyte* %%ptr +internal fastcc sbyte* %gc_malloc_atomic(uint %n) { + %ptr = call ccc sbyte* %GC_malloc_atomic(uint %n) + ret sbyte* %ptr } -""" % locals() +""" -gc_disabled = """%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc(uint %%n) { - %%nn = cast uint %%n to uint - %%ptr = malloc sbyte, uint %%nn - ret sbyte* %%ptr +gc_disabled = """internal fastcc sbyte* %gc_malloc(uint %n) { + %nn = cast uint %n to uint + %ptr = malloc sbyte, uint %nn + ret sbyte* %ptr } -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%gc_malloc_atomic(uint %%n) { - %%nn = cast uint %%n to uint - %%ptr = malloc sbyte, uint %%nn - ret sbyte* %%ptr +internal fastcc sbyte* %gc_malloc_atomic(uint %n) { + %nn = cast uint %n to uint + %ptr = malloc sbyte, uint %nn + ret sbyte* %ptr } -""" % locals() +""" extfunctions = {} #dependencies, llvm-code -import support, ll_os, ll_os_path, ll_time, ll_strtod +import support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod -for module in (support, ll_os, ll_os_path, ll_time, ll_strtod): +for module in (support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod): extdeclarations += module.extdeclarations extfunctions.update(module.extfunctions) extdeclarations += '\n;application function prototypes' Modified: pypy/dist/pypy/translator/llvm2/module/ll_math.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_math.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_math.py Thu Aug 25 17:21:55 2005 @@ -0,0 +1,4 @@ +# XXX Dummy implementation +extdeclarations = "" +extfunctions = {"%ll_math_modf" : (("%prepare_and_raise_OverflowError", "%prepare_and_raise_ValueError"), "")} + Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Thu Aug 25 17:21:55 2005 @@ -1,6 +1,5 @@ extdeclarations = """ ;ll_os.py -declare ccc int %system(sbyte*) declare ccc int %dup(int) declare ccc void %close(int) declare ccc int %open(sbyte*, int, int) @@ -16,26 +15,17 @@ %errno = external global int -%__ll_os_getcwd = constant [12 x sbyte] c"getcwd.....\\00" -%__ll_os_ftruncate = constant [12 x sbyte] c"ftruncate..\\00" -%__ll_os_lseek = constant [12 x sbyte] c"lseek......\\00" -%__ll_os_stat = constant [12 x sbyte] c"stat.......\\00" -%__ll_os_fstat = constant [12 x sbyte] c"fstat......\\00" +%__ll_os_getcwd = internal constant [12 x sbyte] c"getcwd.....\\00" +%__ll_os_ftruncate = internal constant [12 x sbyte] c"ftruncate..\\00" +%__ll_os_lseek = internal constant [12 x sbyte] c"lseek......\\00" +%__ll_os_stat = internal constant [12 x sbyte] c"stat.......\\00" +%__ll_os_fstat = internal constant [12 x sbyte] c"fstat......\\00" """ extfunctions = {} -extfunctions["%ll_os_system"] = (("%cast",), """ -ccc int %ll_os_system(%RPyString* %structstring) { - %dest = call ccc sbyte* %cast(%RPyString* %structstring) - %ret = call ccc int %system(sbyte* %dest) - ret int %ret -} - -""") - extfunctions["%ll_os_dup"] = ((), """ -ccc int %ll_os_dup(int %fd) { +internal fastcc int %ll_os_dup(int %fd) { %ret = call ccc int %dup(int %fd) ret int %ret } @@ -43,22 +33,22 @@ """) extfunctions["%ll_os_getcwd"] = (("%string_to_RPyString", "%__debug"), """ -ccc %RPyString* %ll_os_getcwd() { +internal fastcc %RPyString* %ll_os_getcwd() { - call ccc void %__debug([12 x sbyte]* %__ll_os_getcwd) ; XXX: Test: ll_os_getcwd + call fastcc void %__debug([12 x sbyte]* %__ll_os_getcwd) ; XXX: Test: ll_os_getcwd %s = alloca sbyte, uint 1024 %res = call ccc sbyte* %getcwd(sbyte* %s, int 1023) ;if %res == null: raise... - %cwd = call ccc %RPyString* %string_to_RPyString(sbyte* %s) + %cwd = call fastcc %RPyString* %string_to_RPyString(sbyte* %s) ret %RPyString* %cwd } """) extfunctions["%ll_os_close"] = ((), """ -ccc void %ll_os_close(int %fd) { +internal fastcc void %ll_os_close(int %fd) { call ccc void %close(int %fd) ret void } @@ -66,8 +56,8 @@ """) extfunctions["%ll_os_open"] = (("%cast",), """ -ccc int %ll_os_open(%RPyString* %structstring, int %flag, int %mode) { - %dest = call ccc sbyte* %cast(%RPyString* %structstring) +internal fastcc int %ll_os_open(%RPyString* %structstring, int %flag, int %mode) { + %dest = call fastcc sbyte* %cast(%RPyString* %structstring) %fd = call ccc int %open(sbyte* %dest, int %flag, int %mode) ret int %fd } @@ -75,10 +65,10 @@ """) extfunctions["%ll_os_write"] = (("%cast",), """ -ccc int %ll_os_write(int %fd, %RPyString* %structstring) { +internal fastcc int %ll_os_write(int %fd, %RPyString* %structstring) { %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr - %dest = call ccc sbyte* %cast(%RPyString* %structstring) + %dest = call fastcc sbyte* %cast(%RPyString* %structstring) %byteswritten = call ccc int %write(int %fd, sbyte* %dest, int %reallength) ret int %byteswritten } @@ -86,7 +76,7 @@ """) extfunctions["%ll_read_into"] = ((), """ -ccc int %ll_read_into(int %fd, %RPyString* %structstring) { +internal fastcc int %ll_read_into(int %fd, %RPyString* %structstring) { %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr @@ -100,7 +90,7 @@ """) extfunctions["%ll_os_isatty"] = ((), """ -ccc bool %ll_os_isatty(int %fd) { +internal fastcc bool %ll_os_isatty(int %fd) { %ret = call ccc int %isatty(int %fd) %ret.bool = cast int %ret to bool ret bool %ret.bool @@ -109,8 +99,8 @@ """) extfunctions["%ll_os_ftruncate"] = (("%__debug",), """ -ccc void %ll_os_ftruncate(int %fd, int %length) { - call ccc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: Test: ll_os_ftruncate +internal fastcc void %ll_os_ftruncate(int %fd, int %length) { + call fastcc void %__debug([12 x sbyte]* %__ll_os_ftruncate) ; XXX: Test: ll_os_ftruncate %res = call ccc int %ftruncate(int %fd, int %length) ;if res < 0 raise... ret void @@ -118,8 +108,8 @@ """) extfunctions["%ll_os_lseek"] = (("%__debug",), """ -ccc int %ll_os_lseek(int %fd, int %pos, int %how) { - call ccc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: Test: ll_os_lseek +internal fastcc int %ll_os_lseek(int %fd, int %pos, int %how) { + call fastcc void %__debug([12 x sbyte]* %__ll_os_lseek) ; XXX: Test: ll_os_lseek ;TODO: determine correct %how %res = call ccc int %lseek(int %fd, int %pos, int %how) ;if res < 0 raise... @@ -128,7 +118,7 @@ """) extfunctions["%_stat_construct_result_helper"] = ((), """ -ccc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %src) { +internal fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %src) { %src0ptr = getelementptr [32 x int]* %src, int 0, uint 4 ;st_mode %src1ptr = getelementptr [32 x int]* %src, int 0, uint 3 ;st_ino @@ -154,7 +144,7 @@ %malloc.Size = getelementptr %RPySTAT_RESULT* null, uint 1 %malloc.SizeU = cast %RPySTAT_RESULT* %malloc.Size to uint - %malloc.Ptr = call ccc sbyte* %gc_malloc_atomic(uint %malloc.SizeU) + %malloc.Ptr = call fastcc sbyte* %gc_malloc_atomic(uint %malloc.SizeU) %dest = cast sbyte* %malloc.Ptr to %RPySTAT_RESULT* %dest0ptr = getelementptr %RPySTAT_RESULT* %dest, int 0, uint 0 @@ -184,31 +174,31 @@ """) extfunctions["%ll_os_stat"] = (("%cast", "%__debug", "%_stat_construct_result_helper"), """ -ccc %RPySTAT_RESULT* %ll_os_stat(%RPyString* %s) { +internal fastcc %RPySTAT_RESULT* %ll_os_stat(%RPyString* %s) { - call ccc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat + call fastcc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat %st = alloca [32 x int] - %filename = call ccc sbyte* %cast(%RPyString* %s) + %filename = call fastcc sbyte* %cast(%RPyString* %s) %error = call ccc int %stat(sbyte* %filename, [32 x int]* %st) %cond = seteq int %error, 0 br bool %cond, label %cool, label %bwa bwa: %errno_ = load int* %errno - call ccc void %ll_raise_OSError__Signed(int %errno_) + call fastcc void %ll_raise_OSError__Signed(int %errno_) ret %RPySTAT_RESULT* null cool: - %result = call ccc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) + %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) ret %RPySTAT_RESULT* %result } """) extfunctions["%ll_os_fstat"] = (("%__debug", "%_stat_construct_result_helper"), """ -ccc %RPySTAT_RESULT* %ll_os_fstat(int %fd) { +internal fastcc %RPySTAT_RESULT* %ll_os_fstat(int %fd) { - call ccc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat + call fastcc void %__debug([12 x sbyte]* %__ll_os_fstat) ; XXX: Test: ll_os_fstat %st = alloca [32 x int] %error = call ccc int %fstat(int %fd, [32 x int]* %st) @@ -217,11 +207,11 @@ bwa: %errno_ = load int* %errno - call ccc void %ll_raise_OSError__Signed(int %errno_) + call fastcc void %ll_raise_OSError__Signed(int %errno_) ret %RPySTAT_RESULT* null cool: - %result = call ccc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) + %result = call fastcc %RPySTAT_RESULT* %_stat_construct_result_helper([32 x int]* %st) ret %RPySTAT_RESULT* %result } Modified: pypy/dist/pypy/translator/llvm2/module/ll_strtod.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_strtod.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_strtod.py Thu Aug 25 17:21:55 2005 @@ -1,21 +1,21 @@ extdeclarations = """ ;ll_strtod.py -%__ll_strtod_formatd = constant [12 x sbyte] c"formatd....\\00" -%__ll_strtod_parts_to_float = constant [12 x sbyte] c"parts2flt..\\00" +%__ll_strtod_formatd = internal constant [12 x sbyte] c"formatd....\\00" +%__ll_strtod_parts_to_float = internal constant [12 x sbyte] c"parts2flt..\\00" """ extfunctions = {} extfunctions["%ll_strtod_formatd"] = (("%__debug",), """ -ccc %RPyString* %ll_strtod_formatd(%RPyString* %s, double %x) { - call ccc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd +internal fastcc %RPyString* %ll_strtod_formatd(%RPyString* %s, double %x) { + call fastcc void %__debug([12 x sbyte]* %__ll_strtod_formatd) ; XXX: TODO: ll_strtod_formatd ret %RPyString* null } """) extfunctions["%ll_strtod_parts_to_float"] = (("%__debug",), """ -ccc double %ll_strtod_parts_to_float(%RPyString* s0, %RPyString* s1, %RPyString* s2, %RPyString* s3) { - call ccc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float +internal fastcc double %ll_strtod_parts_to_float(%RPyString* s0, %RPyString* s1, %RPyString* s2, %RPyString* s3) { + call fastcc void %__debug([12 x sbyte]* %__ll_strtod_parts_to_float) ; XXX: TODO: ll_strtod_parts_to_float ret double 0.0 } """) Modified: pypy/dist/pypy/translator/llvm2/module/ll_time.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_time.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_time.py Thu Aug 25 17:21:55 2005 @@ -5,7 +5,7 @@ %struct.timezone = type { int, int } %typedef.fd_set = type { [32 x int] } -%.str_xxx1 = constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] +%.str_xxx1 = internal constant [16 x sbyte] c"select() failed\\00" ; <[16 x sbyte]*> [#uses=1] declare ccc double %floor(double) declare ccc double %fmod(double, double) @@ -19,7 +19,7 @@ extfunctions["%ll_time_time"] = ((), """ -ccc double %ll_time_time() { +internal fastcc double %ll_time_time() { %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] %secs = alloca int ; [#uses=2] %tmp.0 = call int %gettimeofday( %struct.timeval* %t, %struct.timeval* null ) ; [#uses=1] @@ -47,7 +47,7 @@ """) extfunctions["%ll_time_clock"] = ((), """ -ccc double %ll_time_clock() { +internal fastcc double %ll_time_clock() { entry: %tmp.0 = call int %clock( ) ; [#uses=1] %tmp.1 = cast int %tmp.0 to double ; [#uses=1] @@ -57,7 +57,7 @@ """) extfunctions["%ll_time_sleep"] = ((), """ -ccc void %ll_time_sleep(double %secs) { +internal fastcc void %ll_time_sleep(double %secs) { entry: %t = alloca %struct.timeval ; <%struct.timeval*> [#uses=3] %tmp.0 = call double %fmod( double %secs, double 1.000000e+00 ) ; [#uses=1] Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 17:21:55 2005 @@ -1,98 +1,95 @@ -import py -from pypy.translator.llvm2.codewriter import DEFAULT_INTERNAL, DEFAULT_CCONV - extdeclarations = """ -declare ccc double %%pow(double, double) -declare ccc double %%fmod(double, double) -declare ccc int %%puts(sbyte*) -declare ccc int %%strlen(sbyte*) -declare ccc int %%strcmp(sbyte*, sbyte*) -declare ccc sbyte* %%memset(sbyte*, int, uint) - -%%__print_debug_info = %(DEFAULT_INTERNAL)s global bool false -%%__print_debug_info_option = %(DEFAULT_INTERNAL)s constant [19 x sbyte] c"--print-debug-info\\00" -""" % locals() +declare ccc double %pow(double, double) +declare ccc double %fmod(double, double) +declare ccc int %puts(sbyte*) +declare ccc int %strlen(sbyte*) +declare ccc int %strcmp(sbyte*, sbyte*) +declare ccc sbyte* %memset(sbyte*, int, uint) + +%__print_debug_info = internal global bool false +%__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" +""" extfunctions = {} extfunctions["%__debug"] = ((), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s void %%__debug([12 x sbyte]* %%msg12) { - %%cond = load bool* %%__print_debug_info - br bool %%cond, label %%print_it, label %%do_nothing +internal fastcc void %__debug([12 x sbyte]* %msg12) { + %cond = load bool* %__print_debug_info + br bool %cond, label %print_it, label %do_nothing do_nothing: ret void print_it: - %%msg = getelementptr [12 x sbyte]* %%msg12, int 0, int 0 - call int %%puts(sbyte* %%msg) + %msg = getelementptr [12 x sbyte]* %msg12, int 0, int 0 + call int %puts(sbyte* %msg) ret void } -""" % locals()) +""") extfunctions["%cast"] = (("%string_to_RPyString",), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s sbyte* %%cast(%%RPyString* %%structstring) { - %%source1ptr = getelementptr %%RPyString* %%structstring, int 0, uint 1, uint 1 - %%source1 = cast [0 x sbyte]* %%source1ptr to sbyte* - ret sbyte* %%source1 +internal fastcc sbyte* %cast(%RPyString* %structstring) { + %source1ptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 + %source1 = cast [0 x sbyte]* %source1ptr to sbyte* + ret sbyte* %source1 } -""" % locals()) +""") extfunctions["%string_to_RPyString"] = ((), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s %%RPyString* %%string_to_RPyString(sbyte* %%s) { - %%len = call ccc int %%strlen(sbyte* %%s) - %%rpy = call %(DEFAULT_CCONV)s %%RPyString* %%RPyString_New__Signed(int %%len) - %%rpystrptr = getelementptr %%RPyString* %%rpy, int 0, uint 1, uint 1 - %%rpystr = cast [0 x sbyte]* %%rpystrptr to sbyte* +internal fastcc %RPyString* %string_to_RPyString(sbyte* %s) { + %len = call ccc int %strlen(sbyte* %s) + %rpy = call fastcc %RPyString* %RPyString_New__Signed(int %len) + %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 + %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* - call ccc sbyte* %%strncpy(sbyte* %%rpystr, sbyte* %%s, int %%len) + call ccc sbyte* %strncpy(sbyte* %rpystr, sbyte* %s, int %len) - ret %%RPyString* %%rpy + ret %RPyString* %rpy } -""" % locals()) +""") #abs functions extfunctions["%int_abs"] = ((), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_abs(int %%x) { +internal fastcc int %int_abs(int %x) { block0: - %%cond1 = setge int %%x, 0 - br bool %%cond1, label %%return_block, label %%block1 + %cond1 = setge int %x, 0 + br bool %cond1, label %return_block, label %block1 block1: - %%x2 = sub int 0, %%x - br label %%return_block + %x2 = sub int 0, %x + br label %return_block return_block: - %%result = phi int [%%x, %%block0], [%%x2, %%block1] - ret int %%result + %result = phi int [%x, %block0], [%x2, %block1] + ret int %result } -""" % locals()) +""") extfunctions["%float_abs"] = ((), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s double %%float_abs(double %%x) { +internal fastcc double %float_abs(double %x) { block0: - %%cond1 = setge double %%x, 0.0 - br bool %%cond1, label %%return_block, label %%block1 + %cond1 = setge double %x, 0.0 + br bool %cond1, label %return_block, label %block1 block1: - %%x2 = sub double 0.0, %%x - br label %%return_block + %x2 = sub double 0.0, %x + br label %return_block return_block: - %%result = phi double [%%x, %%block0], [%%x2, %%block1] - ret double %%result + %result = phi double [%x, %block0], [%x2, %block1] + ret double %result } -""" % locals()) +""") #prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s void %%__prepare_%(exc)s() { - %%exception_value = call %(DEFAULT_CCONV)s %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() +internal fastcc void %%__prepare_%(exc)s() { + %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type @@ -104,9 +101,9 @@ #prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%prepare_and_raise_%(exc)s" % locals()] = ((), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { +internal fastcc void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { ;XXX %%msg not used right now! - %%exception_value = call %(DEFAULT_CCONV)s %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() + %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type @@ -122,25 +119,25 @@ %%cond = seteq %s %%y, 0 br bool %%cond, label %%is_0, label %%is_not_0 is_0: - call %s void %%__prepare_ZeroDivisionError() + call fastcc void %%__prepare_ZeroDivisionError() unwind is_not_0: """ -int_zer_test = zer_test % ('int' , DEFAULT_CCONV) -double_zer_test = zer_test % ('double', DEFAULT_CCONV) +int_zer_test = zer_test % ('int',) +double_zer_test = zer_test % ('double',) #overflow: normal operation, ...if ((x) >= 0 || (x) != -(x)) OK else _OVF() #note: XXX this hardcoded int32 minint value is used because of a pre llvm1.6 bug! int_ovf_test = """ - %%cond2 = setne int %%x, -2147483648 - br bool %%cond2, label %%return_block, label %%ovf + %cond2 = setne int %x, -2147483648 + br bool %cond2, label %return_block, label %ovf ovf: - call %(DEFAULT_CCONV)s void %%__prepare_OverflowError() + call fastcc void %__prepare_OverflowError() unwind -""" % locals() +""" #binary with ZeroDivisionError only @@ -149,9 +146,9 @@ func, inst = func_inst.split(':') for prefix_type_ in "int:int uint:uint".split(): prefix, type_ = prefix_type_.split(':') - type_zer_test = zer_test % (type_, DEFAULT_CCONV) + type_zer_test = zer_test % type_ extfunctions["%%%(prefix)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s %(type_)s %%%(prefix)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { +internal fastcc %(type_)s %%%(prefix)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { %(type_zer_test)s %%z = %(inst)s %(type_)s %%x, %%y ret %(type_)s %%z @@ -163,7 +160,7 @@ #unary with OverflowError only extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_neg_ovf(int %%x) { +internal fastcc int %%int_neg_ovf(int %%x) { block1: %%x2 = sub int 0, %%x %(int_ovf_test)s @@ -173,7 +170,7 @@ """ % locals()) extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_abs_ovf(int %%x) { +internal fastcc int %%int_abs_ovf(int %%x) { block0: %%cond1 = setge int %%x, 0 br bool %%cond1, label %%return_block, label %%block1 @@ -190,7 +187,7 @@ #binary with OverflowError only extfunctions["%int_add_ovf"] = (("%__prepare_OverflowError",), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_add_ovf(int %%x, int %%y) { +internal fastcc int %%int_add_ovf(int %%x, int %%y) { %%t = add int %%x, %%y %(int_ovf_test)s return_block: @@ -200,7 +197,7 @@ """ % locals()) extfunctions["%int_sub_ovf"] = (("%__prepare_OverflowError",), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_sub_ovf(int %%x, int %%y) { +internal fastcc int %%int_sub_ovf(int %%x, int %%y) { %%t = sub int %%x, %%y %(int_ovf_test)s return_block: @@ -210,7 +207,7 @@ """ % locals()) extfunctions["%int_mul_ovf"] = (("%__prepare_OverflowError",), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_mul_ovf(int %%x, int %%y) { +internal fastcc int %%int_mul_ovf(int %%x, int %%y) { %%t = mul int %%x, %%y %(int_ovf_test)s return_block: @@ -223,7 +220,7 @@ #binary with OverflowError and ValueError extfunctions["%int_lshift_ovf_val"] = (("%__prepare_OverflowError","%__prepare_ValueError"), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_lshift_ovf_val(int %%x, int %%y) { +internal fastcc int %%int_lshift_ovf_val(int %%x, int %%y) { %%yu = cast int %%y to ubyte %%t = shl int %%x, ubyte %%yu %(int_ovf_test)s @@ -237,7 +234,7 @@ #binary with OverflowError and ZeroDivisionError extfunctions["%int_floordiv_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_floordiv_ovf_zer(int %%x, int %%y) { +internal fastcc int %%int_floordiv_ovf_zer(int %%x, int %%y) { %(int_zer_test)s %%t = div int %%x, %%y %(int_ovf_test)s @@ -248,7 +245,7 @@ """ % locals()) extfunctions["%int_mod_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ -%(DEFAULT_INTERNAL)s %(DEFAULT_CCONV)s int %%int_mod_ovf_zer(int %%x, int %%y) { +internal fastcc int %%int_mod_ovf_zer(int %%x, int %%y) { %(int_zer_test)s %%t = rem int %%x, %%y %(int_ovf_test)s @@ -259,40 +256,40 @@ """ % locals()) extfunctions["%main"] = (("%string_to_RPyString"), """ -int %%main(int %%argc, sbyte** %%argv) { +int %main(int %argc, sbyte** %argv) { entry: - %%pypy_argv = call %(DEFAULT_CCONV)s %%RPyListOfString* %%ll_newlist__listPtrConst_Signed.2(int 0) - br label %%no_exit + %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0) + br label %no_exit no_exit: - %%indvar = phi uint [ %%indvar.next, %%next_arg ], [ 0, %%entry ] - %%i.0.0 = cast uint %%indvar to int - %%tmp.8 = getelementptr sbyte** %%argv, uint %%indvar - %%tmp.9 = load sbyte** %%tmp.8 - - %%t = getelementptr [19 x sbyte]* %%__print_debug_info_option, int 0, int 0 - %%res = call ccc int %%strcmp(sbyte* %%tmp.9, sbyte* %%t) - %%cond = seteq int %%res, 0 - br bool %%cond, label %%debugging, label %%not_debugging + %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] + %i.0.0 = cast uint %indvar to int + %tmp.8 = getelementptr sbyte** %argv, uint %indvar + %tmp.9 = load sbyte** %tmp.8 + + %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 + %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) + %cond = seteq int %res, 0 + br bool %cond, label %debugging, label %not_debugging debugging: - store bool true, bool* %%__print_debug_info - br label %%next_arg + store bool true, bool* %__print_debug_info + br label %next_arg not_debugging: - %%rpy = call %(DEFAULT_CCONV)s %%RPyString* %%string_to_RPyString(sbyte* %%tmp.9) - call %(DEFAULT_CCONV)s void %%ll_append__listPtr_rpy_stringPtr(%%RPyListOfString* %%pypy_argv, %%RPyString* %%rpy) - br label %%next_arg + %rpy = call fastcc %RPyString* %string_to_RPyString(sbyte* %tmp.9) + call fastcc void %ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) + br label %next_arg next_arg: - %%inc = add int %%i.0.0, 1 - %%tmp.2 = setlt int %%inc, %%argc - %%indvar.next = add uint %%indvar, 1 - br bool %%tmp.2, label %%no_exit, label %%loopexit + %inc = add int %i.0.0, 1 + %tmp.2 = setlt int %inc, %argc + %indvar.next = add uint %indvar, 1 + br bool %tmp.2, label %no_exit, label %loopexit loopexit: - %%ret = call %(DEFAULT_CCONV)s int %%entry_point(%%structtype.list* %%pypy_argv) - ret int %%ret + %ret = call fastcc int %entry_point(%structtype.list* %pypy_argv) + ret int %ret } -""" % locals()) +""") Modified: pypy/dist/pypy/translator/llvm2/test/test_gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_gc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_gc.py Thu Aug 25 17:21:55 2005 @@ -28,4 +28,4 @@ for i in range(0,25): assert f(n) == result heap_size_inc = get_heap_size() - heap_size_start - assert heap_size_inc < 500000 + assert heap_size_inc < 1000000 Modified: pypy/dist/pypy/translator/llvm2/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/varsize.py (original) +++ pypy/dist/pypy/translator/llvm2/varsize.py Thu Aug 25 17:21:55 2005 @@ -4,7 +4,7 @@ indices_to_array=(), atomicmalloc=False): #varsized arrays and structs look like this: - #Array: {INT length , elemtype*} + #Array: {int length , elemtype*} #Struct: {...., Array} # the following indices access the last element in the array From pedronis at codespeak.net Thu Aug 25 17:26:35 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 25 Aug 2005 17:26:35 +0200 (CEST) Subject: [pypy-svn] r16507 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20050825152635.32F2427B4B@code1.codespeak.net> Author: pedronis Date: Thu Aug 25 17:26:32 2005 New Revision: 16507 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Log: logic to detect when a free varable acces is ambiguous because of parent functions containing bare exec or import * Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Thu Aug 25 17:26:32 2005 @@ -194,6 +194,9 @@ defined. """ + scopeambiguity = False + parentscopeambiguity = False + optimized = 0 # is namespace access optimized? __initialized = None class_name = None # provide default for instance variable @@ -266,7 +269,7 @@ self._nameOp('STORE', name) def loadName(self, name): - if (self.scope.nested and not self.scope.localsfullyknown and + if (self.scope.nested and self.scopeambiguity and name in self.scope.hasbeenfree): raise SyntaxError("cannot reference variable '%s' because " "of ambiguity between " @@ -386,7 +389,8 @@ ndecorators = 0 gen = self.FunctionGen(node, self.scopes, isLambda, - self.class_name, self.get_module()) + self.class_name, self.get_module(), + parentscopeambiguity = self.scopeambiguity or self.parentscopeambiguity) walk(node.code, gen) gen.finish() self.set_lineno(node) @@ -407,7 +411,8 @@ def visitClass(self, node): gen = self.ClassGen(node, self.scopes, - self.get_module()) + self.get_module(), + parentscopeambiguity = self.scopeambiguity or self.parentscopeambiguity) walk(node.code, gen) gen.finish() self.set_lineno(node) @@ -641,7 +646,8 @@ def visitGenExpr(self, node): gen = GenExprCodeGenerator(node, self.scopes, self.class_name, - self.get_module()) + self.get_module(), + parentscopeambiguity=self.scopeambiguity or self.parentscopeambiguity) walk(node.code, gen) gen.finish() self.set_lineno(node) @@ -1353,10 +1359,14 @@ __super_init = AbstractFunctionCode.__init__ - def __init__(self, func, scopes, isLambda, class_name, mod): + def __init__(self, func, scopes, isLambda, class_name, mod, parentscopeambiguity): self.scopes = scopes self.scope = scopes[func] + self.localsfullyknown = self.scope.localsfullyknown + self.parentscopeambiguity = parentscopeambiguity + self.scopeambiguity = (not self.localsfullyknown or parentscopeambiguity) + self.__super_init(func, scopes, isLambda, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) @@ -1370,10 +1380,14 @@ __super_init = AbstractFunctionCode.__init__ - def __init__(self, gexp, scopes, class_name, mod): + def __init__(self, gexp, scopes, class_name, mod, parentscopeambiguity): self.scopes = scopes self.scope = scopes[gexp] + self.localsfullyknown = self.scope.localsfullyknown + self.parentscopeambiguity = parentscopeambiguity + self.scopeambiguity = (not self.localsfullyknown or parentscopeambiguity) + self.__super_init(gexp, scopes, 1, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) @@ -1407,9 +1421,13 @@ __super_init = AbstractClassCode.__init__ - def __init__(self, klass, scopes, module): + def __init__(self, klass, scopes, module, parentscopeambiguity): self.scopes = scopes self.scope = scopes[klass] + + self.parentscopeambiguity = parentscopeambiguity + self.scopeambiguity = parentscopeambiguity + self.__super_init(klass, scopes, module) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) From arigo at codespeak.net Thu Aug 25 17:33:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 17:33:46 +0200 (CEST) Subject: [pypy-svn] r16508 - in pypy/dist/pypy/interpreter: stablecompiler test Message-ID: <20050825153346.A0A0F27B4B@code1.codespeak.net> Author: arigo Date: Thu Aug 25 17:33:45 2005 New Revision: 16508 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/interpreter/test/test_compiler.py Log: * fixed handling of docstrings in stablecompiler, step 1: don't skip the whole first line of a function if there is a docstring (because it can be part of a ';'-separated statements-on-a-single-line). Instead, to avoid to have the docstring in the bytecode as a LOAD_CONST/POP_TOP, we generally skip generating code for any statement that is just a single constant. There is a remaining failure shown by INPROGRESS_test_toplevel_docstring(). * re-enabled test_getcodeflags(), which checks something that has been fixed one or two days ago already. Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Thu Aug 25 17:33:45 2005 @@ -827,6 +827,11 @@ # misc def visitDiscard(self, node): + # Important: this function is overridden in InteractiveCodeGenerator, + # which also has the effect that the following test only occurs in + # non-'single' modes. + if isinstance(node.expr, ast.Const): + return # skip LOAD_CONST/POP_TOP pairs (for e.g. docstrings) self.set_lineno(node) self.visit(node.expr) self.emit('POP_TOP') Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Thu Aug 25 17:33:45 2005 @@ -185,12 +185,8 @@ def file_input(self, nodelist): doc = self.get_docstring(nodelist, symbol.file_input) - if doc is not None: - i = 1 - else: - i = 0 stmts = [] - for node in nodelist[i:]: + for node in nodelist: if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: self.com_append_stmt(stmts, node) return Module(doc, Stmt(stmts)) Modified: pypy/dist/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_compiler.py (original) +++ pypy/dist/pypy/interpreter/test/test_compiler.py Thu Aug 25 17:33:45 2005 @@ -44,7 +44,6 @@ 'if 1:\n x x', '?', 'exec', 0) def test_getcodeflags(self): - py.test.skip("flags don't work correctly when using the compiler package") code = self.compiler.compile('from __future__ import division\n', '', 'exec', 0) flags = self.compiler.getcodeflags(code) @@ -117,6 +116,32 @@ ex = e.value assert ex.match(self.space, self.space.w_SyntaxError) + def INPROGRESS_test_toplevel_docstring(self): + space = self.space + import pdb; pdb.set_trace() + code = self.compiler.compile('"spam"; "bar"; x=5', '', 'exec', 0) + assert space.eq_w(code.co_consts_w[0], space.wrap("spam")) + w_locals = space.newdict([]) + code.exec_code(space, space.newdict([]), w_locals) + w_x = space.getitem(w_locals, space.wrap('x')) + assert space.eq_w(w_x, space.wrap(5)) + # + code = self.compiler.compile('"spam"; "bar"; x=5', + '', 'single', 0) + w_locals = space.newdict([]) + code.exec_code(space, space.newdict([]), w_locals) + w_x = space.getitem(w_locals, space.wrap('x')) + assert space.eq_w(w_x, space.wrap(5)) + + def test_barestringstmts_disappear(self): + space = self.space + code = self.compiler.compile('"a"\n"b"\n"c"\n', '', 'exec', 0) + for w_const in code.co_consts_w: + # "a" should show up as a docstring, but "b" and "c" should not + assert not space.eq_w(w_const, space.wrap("b")) + assert not space.eq_w(w_const, space.wrap("c")) + + class TestECCompiler(BaseTestCompiler): def setup_method(self, method): self.compiler = self.space.getexecutioncontext().compiler From nik at codespeak.net Thu Aug 25 17:37:44 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 17:37:44 +0200 (CEST) Subject: [pypy-svn] r16510 - pypy/dist/pypy/module/_sre Message-ID: <20050825153744.65DA227B4B@code1.codespeak.net> Author: nik Date: Thu Aug 25 17:37:43 2005 New Revision: 16510 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved op_at and op_any to interp-level Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Thu Aug 25 17:37:43 2005 @@ -24,6 +24,5 @@ '_opcode_dispatch': 'interp_sre.opcode_dispatch', '_opcode_is_at_interplevel': 'interp_sre.opcode_is_at_interplevel', '_check_charset': 'interp_sre.check_charset', - '_at_dispatch': 'interp_sre.at_dispatch', '_category_dispatch': 'interp_sre.category_dispatch', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 17:37:43 2005 @@ -454,24 +454,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def general_op_literal(self, ctx, compare, decorate=lambda x: x): - if ctx.at_end() or not compare(decorate(ord(ctx.peek_char())), - decorate(ctx.peek_code(1))): - ctx.has_matched = NOT_MATCHED - ctx.skip_code(2) - ctx.skip_char(1) - - def op_at(self, ctx): - # match at given position - # - #self._log(ctx, "AT", ctx.peek_code(1)) - if not _sre._at_dispatch(ctx.peek_code(1), ctx.state.string, - ctx.string_position, ctx.state.end): - ctx.has_matched = NOT_MATCHED - return True - ctx.skip_code(2) - return True - def op_category(self, ctx): # match at given category # @@ -484,17 +466,6 @@ ctx.skip_char(1) return True - def op_any(self, ctx): - # match anything (except a newline) - # - #self._log(ctx, "ANY") - if ctx.at_end() or ctx.at_linebreak(): - ctx.has_matched = NOT_MATCHED - return True - ctx.skip_code(1) - ctx.skip_char(1) - return True - def op_any_all(self, ctx): # match anything # Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 17:37:43 2005 @@ -180,6 +180,9 @@ return w_child_context def peek_char(self, w_peek=0): + # XXX temporary hack + if w_peek == 0: + w_peek = self.space.wrap(0) return self.space.getitem(self.state.w_string, self.space.add(self.space.wrap(self.string_position), w_peek)) @@ -193,7 +196,10 @@ self.skip_char(self.space.int_w(w_skip_count)) def remaining_chars(self): - return self.space.wrap(self.state.end - self.string_position) + return self.state.end - self.string_position + + def w_remaining_chars(self): + return self.space.wrap(self.remaining_chars()) def peek_code(self, peek=0): return self.space.int_w(self.pattern_codes_w[self.code_position + peek]) @@ -211,7 +217,7 @@ return self.space.wrap(len(self.pattern_codes_w) - self.code_position) def at_beginning(self): - return self.space.newbool(self.string_position == 0) + return self.string_position == 0 def at_end(self): return self.string_position == self.state.end @@ -220,9 +226,16 @@ return self.space.newbool(self.at_end()) def at_linebreak(self): - space = self.space - return space.and_(space.newbool(not space.is_true(self.at_end())), - space.eq(self.peek_char(space.wrap(0)), space.wrap("\n"))) + return not self.at_end() and is_linebreak(self.space, self.peek_char()) + + def at_boundary(self, word_checker): + if self.at_beginning() and self.at_end(): + return False + that = not self.at_beginning() \ + and word_checker(self.space, self.peek_char(self.space.wrap(-1))) + this = not self.at_end() \ + and word_checker(self.space, self.peek_char()) + return this != that W_MatchContext.typedef = TypeDef("W_MatchContext", state = interp_attrproperty_w("state", W_MatchContext), @@ -233,13 +246,11 @@ push_new_context = interp2app(W_MatchContext.push_new_context), peek_char = interp2app(W_MatchContext.peek_char), skip_char = interp2app(W_MatchContext.w_skip_char), - remaining_chars = interp2app(W_MatchContext.remaining_chars), + remaining_chars = interp2app(W_MatchContext.w_remaining_chars), peek_code = interp2app(W_MatchContext.w_peek_code), skip_code = interp2app(W_MatchContext.w_skip_code), remaining_codes = interp2app(W_MatchContext.remaining_codes), - at_beginning = interp2app(W_MatchContext.at_beginning), at_end = interp2app(W_MatchContext.w_at_end), - at_linebreak = interp2app(W_MatchContext.at_linebreak), ) def make_repeat_context(space, w_context): @@ -293,7 +304,7 @@ ctx.skip_char(1) return True -def op_not_literal(self, ctx): +def op_not_literal(space, ctx): # match anything that is not the given literal character # if ctx.at_end() or ctx.peek_char_ord() == ctx.peek_code(1): @@ -302,7 +313,7 @@ ctx.skip_char(1) return True -def op_literal_ignore(self, ctx): +def op_literal_ignore(space, ctx): # match literal regardless of case # if ctx.at_end() or \ @@ -312,7 +323,7 @@ ctx.skip_char(1) return True -def op_not_literal_ignore(self, ctx): +def op_not_literal_ignore(space, ctx): # match literal regardless of case # if ctx.at_end() or \ @@ -322,11 +333,30 @@ ctx.skip_char(1) return True +def op_at(space, ctx): + # match at given position + # + if not at_dispatch(space, ctx.peek_code(1), ctx): + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.skip_code(2) + return True + +def op_any(self, ctx): + # match anything (except a newline) + # + if ctx.at_end() or ctx.at_linebreak(): + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.skip_code(1) + ctx.skip_char(1) + return True + opcode_dispatch_table = [ op_failure, op_success, - None, None, #ANY, ANY_ALL, + op_any, None, #ANY, ANY_ALL, None, None, #ASSERT, ASSERT_NOT, - None, #AT, + op_at, None, #BRANCH, None, #CALL, None, #CATEGORY, @@ -481,26 +511,22 @@ and word_checker(self.space, self.peek_char()) return this != that -def at_dispatch(space, w_atcode, w_string, w_string_position, w_end): - # XXX temporary ugly method signature until we can call this from - # interp-level only - atcode = space.int_w(w_atcode) - if atcode >= len(at_dispatch_table): - return space.newbool(False) - context = MatchContext(space, [], w_string, space.int_w(w_string_position), - space.int_w(w_end)) - function, negate = at_dispatch_table[atcode] +def at_dispatch(space, atcode, context): + try: + function, negate = at_dispatch_table[atcode] + except IndexError: + return False result = function(space, context) if negate: - return space.newbool(not result) + return not result else: - return space.newbool(result) + return result def at_beginning(space, ctx): return ctx.at_beginning() def at_beginning_line(space, ctx): - return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(-1)) + return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(space.wrap(-1))) def at_end(space, ctx): return ctx.at_end() or (ctx.remaining_chars() == 1 and ctx.at_linebreak()) From rxe at codespeak.net Thu Aug 25 17:54:12 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 17:54:12 +0200 (CEST) Subject: [pypy-svn] r16511 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050825155412.D1F2E27B4B@code1.codespeak.net> Author: rxe Date: Thu Aug 25 17:54:10 2005 New Revision: 16511 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/support.py Log: Add ll_time_xxx functions ! (ericvrp/rxe) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 17:54:10 2005 @@ -45,17 +45,18 @@ "%prepare_and_raise_ZeroDivisionError" : True, "%prepare_and_raise_OverflowError" : True, "%prepare_and_raise_ValueError" : True, + "%prepare_and_raise_IOError" : True, } for line in llcode.split('\n'): comment = line.find(';') if comment >= 0: line = line[:comment] line = line.rstrip() - if line[-1:] == '{': - returntype, s = line.split(' ', 1) - funcname , s = s.split('(', 1) - funcnames[funcname] = True - line = '%s %s %s' % ("internal", DEFAULT_CCONV, line,) + #if line[-1:] == '{': + # returntype, s = line.split(' ', 1) + # funcname , s = s.split('(', 1) + # funcnames[funcname] = True + # line = '%s %s %s' % ("", DEFAULT_CCONV, line,) ll_lines.append(line) #patch calls to function that we just declared fastcc @@ -181,6 +182,8 @@ math_fns = 'acos asin atan ceil cos cosh exp fabs floor log log10 atan2 fmod ' math_fns += 'sin sinh sqrt tan tanh frexp modf pow hypot ldexp is_error' fns = [('ll_math_%s' % f) for f in math_fns.split()] + time_fns = "ll_time_time ll_time_clock ll_time_sleep ll_floattime" + fns += time_fns.split() return get_ll(open(p).read(), extern_dir, fns) def gen_llvm_source(self, func=None): Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 25 17:54:10 2005 @@ -38,9 +38,9 @@ extfunctions = {} #dependencies, llvm-code -import support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod +import support, ll_os, ll_os_path, ll_math, ll_strtod -for module in (support, ll_os, ll_os_path, ll_time, ll_math, ll_strtod): +for module in (support, ll_os, ll_os_path, ll_math, ll_strtod): extdeclarations += module.extdeclarations extfunctions.update(module.extfunctions) extdeclarations += '\n;application function prototypes' Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 17:54:10 2005 @@ -16,6 +16,7 @@ void prepare_and_raise_OverflowError(char *); void prepare_and_raise_ValueError(char *); +void prepare_and_raise_IOError(char *); int ll_math_is_error(double x) { @@ -224,3 +225,152 @@ LL_MATH_CHECK_ERROR(m, NULL); return ll_frexp_result__Float_Signed(m, expo); } + +/************************************************************/ + /*** C header subsection: time module ***/ + +#include +#ifndef MS_WINDOWS +# include +#endif + + +/****** clock() ******/ + +#if defined(MS_WINDOWS) && !defined(MS_WIN64) && !defined(__BORLANDC__) +/* Win32 has better clock replacement + XXX Win64 does not yet, but might when the platform matures. */ +#include + +double ll_time_clock(void) +{ + static LARGE_INTEGER ctrStart; + static double divisor = 0.0; + LARGE_INTEGER now; + double diff; + + if (divisor == 0.0) { + LARGE_INTEGER freq; + QueryPerformanceCounter(&ctrStart); + if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { + /* Unlikely to happen - this works on all intel + machines at least! Revert to clock() */ + return clock(); + } + divisor = (double)freq.QuadPart; + } + QueryPerformanceCounter(&now); + diff = (double)(now.QuadPart - ctrStart.QuadPart); + return diff / divisor; +} + +#else /* if !MS_WINDOWS */ + +#ifndef CLOCKS_PER_SEC +#ifdef CLK_TCK +#define CLOCKS_PER_SEC CLK_TCK +#else +#define CLOCKS_PER_SEC 1000000 +#endif +#endif + +double ll_time_clock(void) +{ + return ((double)clock()) / CLOCKS_PER_SEC; +} +#endif /* MS_WINDOWS */ + + +void ll_time_sleep(double secs) +{ +#if defined(MS_WINDOWS) + double millisecs = secs * 1000.0; + unsigned long ul_millis; + + if (millisecs > (double)ULONG_MAX) { + prepare_and_raise_OverflowError("sleep length is too large"); + } + ul_millis = (unsigned long)millisecs; + /* XXX copy CPython to make this interruptible again */ + /*if (ul_millis == 0)*/ + Sleep(ul_millis); + /*else { + DWORD rc; + ResetEvent(hInterruptEvent); + rc = WaitForSingleObject(hInterruptEvent, ul_millis); + if (rc == WAIT_OBJECT_0) { + * Yield to make sure real Python signal + * handler called. + * + Sleep(1); + RPyRaiseSimpleException(PyExc_IOError, "interrupted"); + return; + } + }*/ +#else + struct timeval t; + double frac; + frac = fmod(secs, 1.0); + secs = floor(secs); + t.tv_sec = (long)secs; + t.tv_usec = (long)(frac*1000000.0); + if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) { +#ifdef EINTR + if (errno != EINTR) { +#else + if (1) { +#endif + prepare_and_raise_IOError("select() failed"); + } + } +#endif +} + + +#ifdef HAVE_FTIME +#include +#if !defined(MS_WINDOWS) && !defined(PYOS_OS2) +extern int ftime(struct timeb *); +#endif /* MS_WINDOWS */ +#endif /* HAVE_FTIME */ + +static double +ll_floattime(void) +{ + /* There are three ways to get the time: + (1) gettimeofday() -- resolution in microseconds + (2) ftime() -- resolution in milliseconds + (3) time() -- resolution in seconds + In all cases the return value is a float in seconds. + Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may + fail, so we fall back on ftime() or time(). + Note: clock resolution does not imply clock accuracy! */ +#ifdef HAVE_GETTIMEOFDAY + { + struct timeval t; +#ifdef GETTIMEOFDAY_NO_TZ + if (gettimeofday(&t) == 0) + return (double)t.tv_sec + t.tv_usec*0.000001; +#else /* !GETTIMEOFDAY_NO_TZ */ + if (gettimeofday(&t, (struct timezone *)NULL) == 0) + return (double)t.tv_sec + t.tv_usec*0.000001; +#endif /* !GETTIMEOFDAY_NO_TZ */ + } +#endif /* !HAVE_GETTIMEOFDAY */ + { +#if defined(HAVE_FTIME) + struct timeb t; + ftime(&t); + return (double)t.time + (double)t.millitm * (double)0.001; +#else /* !HAVE_FTIME */ + time_t secs; + time(&secs); + return (double)secs; +#endif /* !HAVE_FTIME */ + } +} + +double ll_time_time(void) /* xxx had support for better resolutions */ +{ + return ll_floattime(); +} Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 17:54:10 2005 @@ -99,7 +99,7 @@ """ % locals()) #prepare exceptions -for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL +for exc in "IOError ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%prepare_and_raise_%(exc)s" % locals()] = ((), """ internal fastcc void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { ;XXX %%msg not used right now! From cfbolz at codespeak.net Thu Aug 25 17:56:24 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 25 Aug 2005 17:56:24 +0200 (CEST) Subject: [pypy-svn] r16512 - in pypy/dist/pypy/rpython: . memory memory/test test Message-ID: <20050825155624.4423027B51@code1.codespeak.net> Author: cfbolz Date: Thu Aug 25 17:56:22 2005 New Revision: 16512 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltype.py pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py pypy/dist/pypy/rpython/test/test_llinterp.py Log: move cast_ptr_to_int to lltype because it is implementation independent. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Aug 25 17:56:22 2005 @@ -341,14 +341,11 @@ assert isinstance(ptr1, self.llt._ptr) return not bool(ptr1) - def op_cast_ptr_to_int(self, ptr1): # xxx should this logic migrate to lltype _ptr itself? + def op_cast_ptr_to_int(self, ptr1): assert isinstance(ptr1, self.llt._ptr) assert isinstance(self.llt.typeOf(ptr1).TO, (self.llt.Array, self.llt.Struct)) - obj = ptr1._obj - while obj._parentstructure(): - obj = obj._parentstructure() - return id(obj) + return self.llt.cast_ptr_to_int(ptr1) def op_cast_int_to_float(self, i): assert type(i) is int Modified: pypy/dist/pypy/rpython/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltype.py (original) +++ pypy/dist/pypy/rpython/lltype.py Thu Aug 25 17:56:22 2005 @@ -853,6 +853,13 @@ o = _pyobject(obj) return _ptr(Ptr(PyObject), o) +def cast_ptr_to_int(ptr): + obj = ptr._obj + while obj._parentstructure(): + obj = obj._parentstructure() + return id(obj) + + def attachRuntimeTypeInfo(GCSTRUCT, funcptr=None): if not isinstance(GCSTRUCT, GcStruct): raise TypeError, "expected a GcStruct: %s" % GCSTRUCT Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Thu Aug 25 17:56:22 2005 @@ -8,7 +8,7 @@ from pypy.rpython.memory.lltypesimulation import cast_pointer from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr -from pypy.rpython.memory.lltypesimulation import pyobjectptr +from pypy.rpython.memory.lltypesimulation import pyobjectptr, cast_ptr_to_int from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Thu Aug 25 17:56:22 2005 @@ -213,3 +213,6 @@ def pyobjectptr(obj): addr = lladdress.get_address_of_object(lltype._pyobject(obj)) return simulatorptr(lltype.Ptr(lltype.PyObject), addr) + +def cast_ptr_to_int(ptr): + return ptr._address.intaddress Modified: pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Thu Aug 25 17:56:22 2005 @@ -308,6 +308,18 @@ res = interpret(f, [4]) assert res == 5 +def test_id(): + def getids(i, j): + e1 = ExampleClass(1) + e2 = ExampleClass(2) + a = [e1, e2][i] + b = [e1, e2][j] + return (id(a) == id(b)) == (a is b) + for i in [0, 1]: + for j in [0, 1]: + result = interpret(getids, [i, j]) + assert result + #__________________________________________________________________ # example functions for testing the LLInterpreter Modified: pypy/dist/pypy/rpython/test/test_llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_llinterp.py (original) +++ pypy/dist/pypy/rpython/test/test_llinterp.py Thu Aug 25 17:56:22 2005 @@ -340,7 +340,17 @@ res = interpret(f, [4]) assert res == 5 - +def test_id(): + def getids(i, j): + e1 = ExampleClass(1) + e2 = ExampleClass(2) + a = [e1, e2][i] + b = [e1, e2][j] + return (id(a) == id(b)) == (a is b) + for i in [0, 1]: + for j in [0, 1]: + result = interpret(getids, [i, j]) + assert result #__________________________________________________________________ # example functions for testing the LLInterpreter _snap = globals().copy() @@ -400,6 +410,7 @@ return i except ValueError: raise TypeError + #__________________________________________________________________ # interactive playing From hpk at codespeak.net Thu Aug 25 18:07:01 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 18:07:01 +0200 (CEST) Subject: [pypy-svn] r16513 - pypy/dist/lib-python Message-ID: <20050825160701.5FB0C27B4E@code1.codespeak.net> Author: hpk Date: Thu Aug 25 18:07:00 2005 New Revision: 16513 Modified: pypy/dist/lib-python/conftest.py Log: aehem. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Aug 25 18:07:00 2005 @@ -879,7 +879,7 @@ # the regrverbose script now does the logic that CPython # uses in its regrtest.py regrrun = str(regr_script) - regrrun_verbosity = regrtest.getoutputpath() and '1' or '0' + regrrun_verbosity = regrtest.getoutputpath() and '0' or '1' TIMEOUT = gettimeout() cmd = "%s %s %d %s %s %s %s %s" %( From ale at codespeak.net Thu Aug 25 18:19:23 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 18:19:23 +0200 (CEST) Subject: [pypy-svn] r16517 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050825161923.9739D27B51@code1.codespeak.net> Author: ale Date: Thu Aug 25 18:19:22 2005 New Revision: 16517 Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Log: (arre, ale) Detect unterminated single quoted strings. Adjust line number in an error Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Thu Aug 25 18:19:22 2005 @@ -124,7 +124,7 @@ if contstr: # continued string if not line: raise TokenError("EOF while scanning triple-quoted string", line, - (lnum, 0), token_list) + (lnum-1, 0), token_list) endmatch = endDFA.recognize(line) if endmatch >= 0: pos = end = endmatch @@ -277,6 +277,12 @@ token_list.append((tok, line, lnum, pos)) last_comment = '' else: + start = whiteSpaceDFA.recognize(line, pos) + if start < 0: + start = pos + if start Author: arigo Date: Thu Aug 25 18:23:01 2005 New Revision: 16519 Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/interpreter/test/test_compiler.py Log: * in the pyparser, use the single_input grammar target. * in the st->ast transformer, produce the correct ast for single_input. * enable the now-passing test_toplevel_docstring(). * this introduces some failures in test_astbuilder because it is comparing its own output with the above-mentioned st->ast transformer, so it is mimicking the bug. Will try to fix astbuilder.py... Modified: pypy/dist/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonutil.py Thu Aug 25 18:23:01 2005 @@ -12,7 +12,7 @@ TARGET_DICT = { 'exec' : "file_input", 'eval' : "eval_input", - 'single' : "file_input", + 'single' : "single_input", } ## convenience functions around CPython's parser functions Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Thu Aug 25 18:23:01 2005 @@ -175,13 +175,13 @@ raise WalkerError, ('unexpected node type', n) def single_input(self, node): - ### do we want to do anything about being "interactive" ? # NEWLINE | simple_stmt | compound_stmt NEWLINE n = node[0][0] if n != token.NEWLINE: - return self.com_stmt(node[0]) - - return Pass() + stmt = self.com_stmt(node[0]) + else: + stmt = Pass() + return Module(None, stmt) def file_input(self, nodelist): doc = self.get_docstring(nodelist, symbol.file_input) Modified: pypy/dist/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_compiler.py (original) +++ pypy/dist/pypy/interpreter/test/test_compiler.py Thu Aug 25 18:23:01 2005 @@ -116,15 +116,15 @@ ex = e.value assert ex.match(self.space, self.space.w_SyntaxError) - def INPROGRESS_test_toplevel_docstring(self): + def test_toplevel_docstring(self): space = self.space - import pdb; pdb.set_trace() code = self.compiler.compile('"spam"; "bar"; x=5', '', 'exec', 0) - assert space.eq_w(code.co_consts_w[0], space.wrap("spam")) w_locals = space.newdict([]) code.exec_code(space, space.newdict([]), w_locals) w_x = space.getitem(w_locals, space.wrap('x')) assert space.eq_w(w_x, space.wrap(5)) + w_doc = space.getitem(w_locals, space.wrap('__doc__')) + assert space.eq_w(w_doc, space.wrap("spam")) # code = self.compiler.compile('"spam"; "bar"; x=5', '', 'single', 0) @@ -132,6 +132,8 @@ code.exec_code(space, space.newdict([]), w_locals) w_x = space.getitem(w_locals, space.wrap('x')) assert space.eq_w(w_x, space.wrap(5)) + w_doc = space.call_method(w_locals, 'get', space.wrap('__doc__')) + assert space.is_w(w_doc, space.w_None) # "spam" is not a docstring def test_barestringstmts_disappear(self): space = self.space From nik at codespeak.net Thu Aug 25 18:36:03 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 18:36:03 +0200 (CEST) Subject: [pypy-svn] r16521 - pypy/dist/pypy/module/_sre Message-ID: <20050825163603.DFDDA27B49@code1.codespeak.net> Author: nik Date: Thu Aug 25 18:36:02 2005 New Revision: 16521 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved more op_methods to interp-level. refactored duplicated MatchContext away. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Thu Aug 25 18:36:02 2005 @@ -23,6 +23,4 @@ '_RepeatContext': 'interp_sre.make_repeat_context', '_opcode_dispatch': 'interp_sre.opcode_dispatch', '_opcode_is_at_interplevel': 'interp_sre.opcode_is_at_interplevel', - '_check_charset': 'interp_sre.check_charset', - '_category_dispatch': 'interp_sre.category_dispatch', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 18:36:02 2005 @@ -454,58 +454,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def op_category(self, ctx): - # match at given category - # - #self._log(ctx, "CATEGORY", ctx.peek_code(1)) - if ctx.at_end() or \ - not _sre._category_dispatch(ctx.peek_code(1), ctx.peek_char()): - ctx.has_matched = NOT_MATCHED - return True - ctx.skip_code(2) - ctx.skip_char(1) - return True - - def op_any_all(self, ctx): - # match anything - # - #self._log(ctx, "ANY_ALL") - if ctx.at_end(): - ctx.has_matched = NOT_MATCHED - return True - ctx.skip_code(1) - ctx.skip_char(1) - return True - - def general_op_in(self, ctx, decorate=lambda x: x): - #self._log(ctx, "OP_IN") - if ctx.at_end(): - ctx.has_matched = NOT_MATCHED - return - skip = ctx.peek_code(1) - ctx.skip_code(2) # set op pointer to the set code - char = decorate(ord(ctx.peek_char())) - if not _sre._check_charset(ctx.pattern_codes[ctx.code_position:], char, - ctx.state.string, ctx.string_position): - ctx.has_matched = NOT_MATCHED - return - ctx.skip_code(skip - 1) - ctx.skip_char(1) - - def op_in(self, ctx): - # match set member (or non_member) - # - #self._log(ctx, "OP_IN") - self.general_op_in(ctx) - return True - - def op_in_ignore(self, ctx): - # match set member (or non_member), disregarding case of current char - # - #self._log(ctx, "OP_IN_IGNORE") - self.general_op_in(ctx, ctx.state.lower) - return True - def op_jump(self, ctx): # jump forward # Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 18:36:02 2005 @@ -282,7 +282,10 @@ def opcode_is_at_interplevel(space, w_opcode): opcode = space.int_w(w_opcode) - return space.newbool(opcode_dispatch_table[opcode] is not None) + try: + return space.newbool(opcode_dispatch_table[opcode] is not None) + except IndexError: + return space.newbool(False) def op_success(space, ctx): # end of pattern @@ -342,6 +345,17 @@ ctx.skip_code(2) return True +def op_category(space, ctx): + # match at given category + # + if ctx.at_end() or \ + not category_dispatch(space, ctx.peek_code(1), ctx.peek_char()): + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.skip_code(2) + ctx.skip_char(1) + return True + def op_any(self, ctx): # match anything (except a newline) # @@ -352,17 +366,54 @@ ctx.skip_char(1) return True +def op_any_all(space, ctx): + # match anything + # + if ctx.at_end(): + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.skip_code(1) + ctx.skip_char(1) + return True + +def general_op_in(space, ctx, ignore=False): + if ctx.at_end(): + ctx.has_matched = ctx.NOT_MATCHED + return + skip = ctx.peek_code(1) + ctx.skip_code(2) # set op pointer to the set code + char_code = space.int_w(space.ord(ctx.peek_char())) + if ignore: + char_code = ctx.state.lower(char_code) + if not check_charset(space, char_code, ctx): + ctx.has_matched = ctx.NOT_MATCHED + return + ctx.skip_code(skip - 1) + ctx.skip_char(1) + +def op_in(space, ctx): + # match set member (or non_member) + # + general_op_in(space, ctx) + return True + +def op_in_ignore(space, ctx): + # match set member (or non_member), disregarding case of current char + # + general_op_in(space, ctx, ignore=True) + return True + opcode_dispatch_table = [ op_failure, op_success, - op_any, None, #ANY, ANY_ALL, + op_any, op_any_all, None, None, #ASSERT, ASSERT_NOT, op_at, None, #BRANCH, None, #CALL, - None, #CATEGORY, + op_category, None, None, #CHARSET, BIGCHARSET, None, None, None, #GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE, - None, None, #IN, IN_IGNORE, + op_in, op_in_ignore, None, #INFO, None, #JUMP, op_literal, op_literal_ignore, @@ -439,16 +490,16 @@ #### Category dispatch -def category_dispatch(space, w_chcode, w_char): - chcode = space.int_w(w_chcode) - if chcode >= len(category_dispatch_table): - return space.newbool(False) - function, negate = category_dispatch_table[chcode] +def category_dispatch(space, chcode, w_char): + try: + function, negate = category_dispatch_table[chcode] + except IndexError: + return False result = function(space, w_char) if negate: - return space.newbool(not result) + return not result else: - return space.newbool(result) + return result # Maps opcodes by indices to (function, negate) tuples. category_dispatch_table = [ @@ -463,54 +514,6 @@ ##### At dispatch -class MatchContext: - # XXX This is not complete. It's tailored to at dispatch currently. - - # XXX These constants should maybe not be here - OK = 1 - NOT_OK = -1 - NOT_FINISHED = 0 - - def __init__(self, space, pattern_codes, w_string, string_position, end): - self.space = space - self.pattern_codes = pattern_codes - self.w_string = w_string - self.string_position = string_position - self.end = end - self.code_position = 0 - self.set_ok = self.OK # XXX maybe get rid of this - - def peek_char(self, peek=0): - return self.space.getitem(self.w_string, - self.space.wrap(self.string_position + peek)) - - def remaining_chars(self): - return self.end - self.string_position - - def peek_code(self, peek=0): - return self.pattern_codes[self.code_position + peek] - - def skip_code(self, skip_count): - self.code_position += skip_count - - def at_beginning(self): - return self.string_position == 0 - - def at_end(self): - return self.string_position == self.end - - def at_linebreak(self): - return not self.at_end() and is_linebreak(self.space, self.peek_char()) - - def at_boundary(self, word_checker): - if self.at_beginning() and self.at_end(): - return False - that = not self.at_beginning() \ - and word_checker(self.space, self.peek_char(-1)) - this = not self.at_end() \ - and word_checker(self.space, self.peek_char()) - return this != that - def at_dispatch(space, atcode, context): try: function, negate = at_dispatch_table[atcode] @@ -557,24 +560,25 @@ ##### Charset evaluation -def check_charset(space, w_pattern_codes, w_char_code, w_string, w_string_position): +SET_OK = 1 +SET_NOT_OK = -1 +SET_NOT_FINISHED = 0 + +def check_charset(space, char_code, context): """Checks whether a character matches set of arbitrary length. Currently assumes the set starts at the first member of pattern_codes.""" - # XXX temporary ugly method signature until we can call this from - # interp-level only - pattern_codes_w = space.unpackiterable(w_pattern_codes) - pattern_codes = [space.int_w(code) for code in pattern_codes_w] - char_code = space.int_w(w_char_code) - context = MatchContext(space, pattern_codes, w_string, - space.int_w(w_string_position), space.int_w(space.len(w_string))) - result = MatchContext.NOT_FINISHED - while result == MatchContext.NOT_FINISHED: + result = SET_NOT_FINISHED + context.set_ok = SET_OK + backup_code_position = context.code_position + while result == SET_NOT_FINISHED: opcode = context.peek_code() - if opcode >= len(set_dispatch_table): - return space.newbool(False) - function = set_dispatch_table[opcode] + try: + function = set_dispatch_table[opcode] + except IndexError: + return False result = function(space, context, char_code) - return space.newbool(result == MatchContext.OK) + context.code_position = backup_code_position + return result == SET_OK def set_failure(space, ctx, char_code): return -ctx.set_ok @@ -585,16 +589,15 @@ return ctx.set_ok else: ctx.skip_code(2) - return MatchContext.NOT_FINISHED + return SET_NOT_FINISHED def set_category(space, ctx, char_code): # - if space.is_true( - category_dispatch(space, space.wrap(ctx.peek_code(1)), ctx.peek_char())): + if category_dispatch(space, ctx.peek_code(1), ctx.peek_char()): return ctx.set_ok else: ctx.skip_code(2) - return MatchContext.NOT_FINISHED + return SET_NOT_FINISHED def set_charset(space, ctx, char_code): # (16 bits per code word) @@ -609,19 +612,19 @@ & (1 << (char_code & 31)): return ctx.set_ok ctx.skip_code(8) # skip bitmap - return MatchContext.NOT_FINISHED + return SET_NOT_FINISHED def set_range(space, ctx, char_code): # if ctx.peek_code(1) <= char_code <= ctx.peek_code(2): return ctx.set_ok ctx.skip_code(3) - return MatchContext.NOT_FINISHED + return SET_NOT_FINISHED def set_negate(space, ctx, char_code): ctx.set_ok = -ctx.set_ok ctx.skip_code(1) - return MatchContext.NOT_FINISHED + return SET_NOT_FINISHED def set_bigcharset(space, ctx, char_code): # <256 blockindices> @@ -645,7 +648,7 @@ else: ctx.skip_code(256 / CODESIZE) # skip block indices ctx.skip_code(count * (32 / CODESIZE)) # skip blocks - return MatchContext.NOT_FINISHED + return SET_NOT_FINISHED def to_byte_array(int_value): """Creates a list of bytes out of an integer representing data that is From ericvrp at codespeak.net Thu Aug 25 18:49:17 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 18:49:17 +0200 (CEST) Subject: [pypy-svn] r16522 - pypy/dist/pypy/translator/llvm2/test Message-ID: <20050825164917.2CA6F27B49@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 18:49:15 2005 New Revision: 16522 Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py Log: removed test that should not be here Modified: pypy/dist/pypy/translator/llvm2/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_typed.py Thu Aug 25 18:49:15 2005 @@ -264,16 +264,6 @@ f = compile_function(wrapper, [int]) assert f(42) -def test_float2int(): - py.test.skip("RTyper is cheating") - def fn(f): - return str(f) - def wrapper(): - res = fn(1.0) - return res == "1.0" - f = compile_function(wrapper, []) - assert f() - def test_int_invert(): def fn(i): return ~i From rxe at codespeak.net Thu Aug 25 18:51:33 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 18:51:33 +0200 (CEST) Subject: [pypy-svn] r16523 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050825165133.67EB227B49@code1.codespeak.net> Author: rxe Date: Thu Aug 25 18:51:32 2005 New Revision: 16523 Removed: pypy/dist/pypy/translator/llvm2/module/ll_math.py pypy/dist/pypy/translator/llvm2/module/ll_strtod.py pypy/dist/pypy/translator/llvm2/module/ll_time.py Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/support.py Log: Intermediate checkin after refactoring names to be similar to genc: RPyString_FromString, RPyString_AsString and RPyString_Size. Added LL_strtod_formatd() - not tested yet. Tidied up and removed most of module/ll_xxx files. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 18:51:32 2005 @@ -322,6 +322,8 @@ if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy extfuncnode.ExternalFuncNode.used_external_functions['%main'] = True + extfuncnode.ExternalFuncNode.used_external_functions['%RPyString_FromString'] = True + if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() depdone = {} for funcname,value in extfuncnode.ExternalFuncNode.used_external_functions.iteritems(): Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 25 18:51:32 2005 @@ -38,9 +38,9 @@ extfunctions = {} #dependencies, llvm-code -import support, ll_os, ll_os_path, ll_math, ll_strtod +import support, ll_os -for module in (support, ll_os, ll_os_path, ll_math, ll_strtod): +for module in (support, ll_os): extdeclarations += module.extdeclarations extfunctions.update(module.extfunctions) extdeclarations += '\n;application function prototypes' Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 18:51:32 2005 @@ -1,4 +1,6 @@ #include +#include +#include #include #define NULL (void *) 0 @@ -10,6 +12,7 @@ struct RPyFREXP_RESULT; struct RPyMODF_RESULT; +struct RPyString; struct RPyFREXP_RESULT *ll_frexp_result__Float_Signed(double, int); struct RPyMODF_RESULT *ll_modf_result__Float_Float(double, double); @@ -18,7 +21,6 @@ void prepare_and_raise_ValueError(char *); void prepare_and_raise_IOError(char *); - int ll_math_is_error(double x) { if (errno == ERANGE) { if (!x) @@ -374,3 +376,109 @@ { return ll_floattime(); } + +double ll_strtod_parts_to_float(struct RPyString *sign, + struct RPyString *beforept, + struct RPyString *afterpt, + struct RPyString *exponent) +{ + char *fail_pos; + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + double x; + char *last; + char *expo = RPyString_AsString(exponent); + int buf_size; + char *s; + + if (*expo == '\0') { + expo = "0"; + } + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + buf_size = RPyString_Size(sign) + + RPyString_Size(beforept) + + decimal_point_len + + RPyString_Size(afterpt) + + 1 /* e */ + + strlen(expo) + + 1 /* asciiz */ ; + + s = malloc(buf_size); + + strcpy(s, RPyString_AsString(sign)); + strcat(s, RPyString_AsString(beforept)); + strcat(s, decimal_point); + strcat(s, RPyString_AsString(afterpt)); + strcat(s, "e"); + strcat(s, expo); + + last = s + (buf_size-1); + x = strtod(s, &fail_pos); + errno = 0; + free(s); + if (fail_pos > last) + fail_pos = last; + if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { + RPyRaiseSimpleException(PyExc_ValueError, "invalid float literal"); + return -1.0; + } + if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ + x = strtod(s, NULL); + errno = 0; + } + return x; +} + + +struct RPyString *LL_strtod_formatd(struct RPyString *fmt, double x) { + char buffer[120]; /* this should be enough, from PyString_Format code */ + int buflen = 120; + int res; + res = snprintf(buffer, buflen, RPyString_AsString(fmt), x); + if (res <= 0 || res >= buflen) { + strcpy(buffer, "??.?"); /* should not occur */ + } else { + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + char *p; + + locale_data = localeconv(); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen(decimal_point); + + if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + p = buffer; + + if (*p == '+' || *p == '-') + p++; + + while (isdigit((unsigned char)*p)) + p++; + + if (strncmp(p, decimal_point, decimal_point_len) == 0) + { + *p = '.'; + p++; + if (decimal_point_len > 1) { + int rest_len; + rest_len = strlen(p + (decimal_point_len - 1)); + memmove(p, p + (decimal_point_len - 1), + rest_len); + p[rest_len] = 0; + } + } + } + + } + + return RPyString_FromString(buffer); +} + Modified: pypy/dist/pypy/translator/llvm2/module/ll_os.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/ll_os.py (original) +++ pypy/dist/pypy/translator/llvm2/module/ll_os.py Thu Aug 25 18:51:32 2005 @@ -32,7 +32,7 @@ """) -extfunctions["%ll_os_getcwd"] = (("%string_to_RPyString", "%__debug"), """ +extfunctions["%ll_os_getcwd"] = (("%RPyString_FromString", "%__debug"), """ internal fastcc %RPyString* %ll_os_getcwd() { call fastcc void %__debug([12 x sbyte]* %__ll_os_getcwd) ; XXX: Test: ll_os_getcwd @@ -41,7 +41,7 @@ %res = call ccc sbyte* %getcwd(sbyte* %s, int 1023) ;if %res == null: raise... - %cwd = call fastcc %RPyString* %string_to_RPyString(sbyte* %s) + %cwd = call fastcc %RPyString* %RPyString_FromString(sbyte* %s) ret %RPyString* %cwd } @@ -55,20 +55,20 @@ """) -extfunctions["%ll_os_open"] = (("%cast",), """ +extfunctions["%ll_os_open"] = (("%RPyString_AsString",), """ internal fastcc int %ll_os_open(%RPyString* %structstring, int %flag, int %mode) { - %dest = call fastcc sbyte* %cast(%RPyString* %structstring) + %dest = call fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) %fd = call ccc int %open(sbyte* %dest, int %flag, int %mode) ret int %fd } """) -extfunctions["%ll_os_write"] = (("%cast",), """ +extfunctions["%ll_os_write"] = (("%RPyString_AsString",), """ internal fastcc int %ll_os_write(int %fd, %RPyString* %structstring) { %reallengthptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %reallength = load int* %reallengthptr - %dest = call fastcc sbyte* %cast(%RPyString* %structstring) + %dest = call fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) %byteswritten = call ccc int %write(int %fd, sbyte* %dest, int %reallength) ret int %byteswritten } @@ -173,13 +173,13 @@ } """) -extfunctions["%ll_os_stat"] = (("%cast", "%__debug", "%_stat_construct_result_helper"), """ +extfunctions["%ll_os_stat"] = (("%RPyString_AsString", "%__debug", "%_stat_construct_result_helper"), """ internal fastcc %RPySTAT_RESULT* %ll_os_stat(%RPyString* %s) { call fastcc void %__debug([12 x sbyte]* %__ll_os_stat) ; XXX: Test: ll_os_stat %st = alloca [32 x int] - %filename = call fastcc sbyte* %cast(%RPyString* %s) + %filename = call fastcc sbyte* %RPyString_AsString(%RPyString* %s) %error = call ccc int %stat(sbyte* %filename, [32 x int]* %st) %cond = seteq int %error, 0 br bool %cond, label %cool, label %bwa Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 18:51:32 2005 @@ -1,3 +1,4 @@ + extdeclarations = """ declare ccc double %pow(double, double) declare ccc double %fmod(double, double) @@ -29,8 +30,8 @@ """) -extfunctions["%cast"] = (("%string_to_RPyString",), """ -internal fastcc sbyte* %cast(%RPyString* %structstring) { +extfunctions["%RPyString_AsString"] = (("%RPyString_FromString",), """ +internal fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) { %source1ptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 %source1 = cast [0 x sbyte]* %source1ptr to sbyte* ret sbyte* %source1 @@ -38,8 +39,19 @@ """) -extfunctions["%string_to_RPyString"] = ((), """ -internal fastcc %RPyString* %string_to_RPyString(sbyte* %s) { +extfunctions["%RPyString_Size"] = ((), """ +internal fastcc int %RPyString_Size(%RPyString* %structstring) { + %sizeptr = getelementptr %RPyString* %structstring, int 0, uint 0 + %size = load int* %sizeptr + return %size + +} + +""") + + +extfunctions["%RPyString_FromString"] = ((), """ +internal fastcc %RPyString* %RPyString_FromString(sbyte* %s) { %len = call ccc int %strlen(sbyte* %s) %rpy = call fastcc %RPyString* %RPyString_New__Signed(int %len) %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 @@ -255,7 +267,7 @@ } """ % locals()) -extfunctions["%main"] = (("%string_to_RPyString"), """ +extfunctions["%main"] = ((), """ int %main(int %argc, sbyte** %argv) { entry: %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0) @@ -277,7 +289,7 @@ br label %next_arg not_debugging: - %rpy = call fastcc %RPyString* %string_to_RPyString(sbyte* %tmp.9) + %rpy = call fastcc %RPyString* %RPyString_FromString(sbyte* %tmp.9) call fastcc void %ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) br label %next_arg From ale at codespeak.net Thu Aug 25 19:05:48 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 19:05:48 +0200 (CEST) Subject: [pypy-svn] r16526 - pypy/dist/lib-python Message-ID: <20050825170548.35AA827B4B@code1.codespeak.net> Author: ale Date: Thu Aug 25 19:05:47 2005 New Revision: 16526 Modified: pypy/dist/lib-python/conftest.py Log: (arre, ale) Use --oldstyle to make test_repr pass. Changed core from "ill-defined" to True Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Aug 25 19:05:47 2005 @@ -629,7 +629,7 @@ RegrTest('test_re.py', enabled=True, core=True), RegrTest('test_regex.py', enabled=False), - RegrTest('test_repr.py', enabled=True, core="ill-defined"), + RegrTest('test_repr.py', enabled=True, oldstyle=True, core=True), #rev 10840: 6 of 12 tests fail. Always minor stuff like #'' != '' From rxe at codespeak.net Thu Aug 25 19:05:56 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 19:05:56 +0200 (CEST) Subject: [pypy-svn] r16527 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050825170556.580EC27B52@code1.codespeak.net> Author: rxe Date: Thu Aug 25 19:05:55 2005 New Revision: 16527 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/support.py Log: More progress towards ll_strtod_formatd. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 19:05:55 2005 @@ -40,6 +40,9 @@ #find function names, declare them internal with fastcc calling convertion ll_lines = [] funcnames = { + "%RPyString_Size" : True, + "%RPyString_AsString" : True, + "%RPyString_FromString" : True, "%ll_frexp_result__Float_Signed" : True, "%ll_modf_result__Float_Float" : True, "%prepare_and_raise_ZeroDivisionError" : True, @@ -184,6 +187,7 @@ fns = [('ll_math_%s' % f) for f in math_fns.split()] time_fns = "ll_time_time ll_time_clock ll_time_sleep ll_floattime" fns += time_fns.split() + fns.append('ll_strtod_formatd') return get_ll(open(p).read(), extern_dir, fns) def gen_llvm_source(self, func=None): Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 19:05:55 2005 @@ -17,6 +17,10 @@ struct RPyFREXP_RESULT *ll_frexp_result__Float_Signed(double, int); struct RPyMODF_RESULT *ll_modf_result__Float_Float(double, double); +char *RPyString_AsString(struct RPyString*); +int RPyString_Size(struct RPyString_Size*); +struct RPyString *RPyString_FromString(char *); + void prepare_and_raise_OverflowError(char *); void prepare_and_raise_ValueError(char *); void prepare_and_raise_IOError(char *); @@ -424,7 +428,7 @@ if (fail_pos > last) fail_pos = last; if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { - RPyRaiseSimpleException(PyExc_ValueError, "invalid float literal"); + prepare_and_raise_ValueError("invalid float literal"); return -1.0; } if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ @@ -435,7 +439,7 @@ } -struct RPyString *LL_strtod_formatd(struct RPyString *fmt, double x) { +struct RPyString *ll_strtod_formatd(struct RPyString *fmt, double x) { char buffer[120]; /* this should be enough, from PyString_Format code */ int buflen = 120; int res; Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 19:05:55 2005 @@ -49,7 +49,6 @@ """) - extfunctions["%RPyString_FromString"] = ((), """ internal fastcc %RPyString* %RPyString_FromString(sbyte* %s) { %len = call ccc int %strlen(sbyte* %s) From rxe at codespeak.net Thu Aug 25 19:20:41 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 19:20:41 +0200 (CEST) Subject: [pypy-svn] r16531 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050825172041.2DBDD27B4B@code1.codespeak.net> Author: rxe Date: Thu Aug 25 19:20:40 2005 New Revision: 16531 Modified: pypy/dist/pypy/translator/llvm2/module/support.py Log: Wrong size of string it would seem (as per genc) Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 19:20:40 2005 @@ -41,7 +41,7 @@ extfunctions["%RPyString_Size"] = ((), """ internal fastcc int %RPyString_Size(%RPyString* %structstring) { - %sizeptr = getelementptr %RPyString* %structstring, int 0, uint 0 + %sizeptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %size = load int* %sizeptr return %size From nik at codespeak.net Thu Aug 25 19:28:00 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 19:28:00 +0200 (CEST) Subject: [pypy-svn] r16532 - pypy/dist/pypy/module/_sre Message-ID: <20050825172800.E40F627B4B@code1.codespeak.net> Author: nik Date: Thu Aug 25 19:27:59 2005 New Revision: 16532 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved more op_methods to interp-level. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 19:27:59 2005 @@ -454,25 +454,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def op_jump(self, ctx): - # jump forward - # - #self._log(ctx, "JUMP", ctx.peek_code(1)) - ctx.skip_code(ctx.peek_code(1) + 1) - return True - - # skip info - # - op_info = op_jump - - def op_mark(self, ctx): - # set mark - # - #self._log(ctx, "OP_MARK", ctx.peek_code(1)) - ctx.state.set_mark(ctx.peek_code(1), ctx.string_position) - ctx.skip_code(2) - return True - def op_branch(self, ctx): # alternation # <0=skip> code ... @@ -718,43 +699,6 @@ ctx.state.string_position = ctx.string_position yield True - def general_op_groupref(self, ctx, decorate=lambda x: x): - group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) - if group_start is None or group_end is None or group_end < group_start: - ctx.has_matched = NOT_MATCHED - return True - while group_start < group_end: - if ctx.at_end() or decorate(ord(ctx.peek_char())) \ - != decorate(ord(ctx.state.string[group_start])): - ctx.has_matched = NOT_MATCHED - return True - group_start += 1 - ctx.skip_char(1) - ctx.skip_code(2) - return True - - def op_groupref(self, ctx): - # match backreference - # - #self._log(ctx, "GROUPREF", ctx.peek_code(1)) - return self.general_op_groupref(ctx) - - def op_groupref_ignore(self, ctx): - # match backreference case-insensitive - # - #self._log(ctx, "GROUPREF_IGNORE", ctx.peek_code(1)) - return self.general_op_groupref(ctx, ctx.state.lower) - - def op_groupref_exists(self, ctx): - # codeyes codeno ... - #self._log(ctx, "GROUPREF_EXISTS", ctx.peek_code(1)) - group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) - if group_start is None or group_end is None or group_end < group_start: - ctx.skip_code(ctx.peek_code(2) + 1) - else: - ctx.skip_code(3) - return True - def op_assert(self, ctx): # assert subpattern # Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 19:27:59 2005 @@ -59,22 +59,20 @@ self.w_context_stack = self.space.newlist([]) self.w_repeat = self.space.w_None - def set_mark(self, w_mark_nr, w_position): - mark_nr = self.space.int_w(w_mark_nr) + def set_mark(self, mark_nr, position): if mark_nr & 1: # This id marks the end of a group. self.lastindex = mark_nr / 2 + 1 if mark_nr >= len(self.marks): self.marks.extend([-1] * (mark_nr - len(self.marks) + 1)) - self.marks[mark_nr] = self.space.int_w(w_position) + self.marks[mark_nr] = position - def get_marks(self, w_group_index): - marks_index = 2 * self.space.int_w(w_group_index) + def get_marks(self, group_index): + marks_index = 2 * group_index if len(self.marks) > marks_index + 1: - return self.space.newtuple([self.space.wrap(self.marks[marks_index]), - self.space.wrap(self.marks[marks_index + 1])]) + return self.marks[marks_index], self.marks[marks_index + 1] else: - return self.space.newtuple([self.space.w_None, self.space.w_None]) + return -1, -1 def create_regs(self, w_group_count): """Creates a tuple of index pairs representing matched groups, a format @@ -140,8 +138,6 @@ context_stack = interp_attrproperty_w("w_context_stack", W_State), repeat = interp_attrproperty_obj_w("w_repeat", W_State), reset = interp2app(W_State.reset), - set_mark = interp2app(W_State.set_mark), - get_marks = interp2app(W_State.get_marks), create_regs = interp2app(W_State.create_regs), marks_push = interp2app(W_State.marks_push), marks_pop = interp2app(W_State.marks_pop), @@ -403,6 +399,58 @@ general_op_in(space, ctx, ignore=True) return True +def op_jump(space, ctx): + # jump forward + # / + ctx.skip_code(ctx.peek_code(1) + 1) + return True + +def op_mark(space, ctx): + # set mark + # + ctx.state.set_mark(ctx.peek_code(1), ctx.string_position) + ctx.skip_code(2) + return True + +def general_op_groupref(space, ctx, ignore=False): + group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) + if group_start == -1 or group_end == -1 or group_end < group_start \ + or group_end - group_start > ctx.remaining_chars(): + ctx.has_matched = ctx.NOT_MATCHED + return True + while group_start < group_end: + # XXX This is really a bit unwieldy. Can this be improved? + new_char = space.int_w(space.ord(ctx.peek_char())) + old_char = space.int_w(space.ord( + space.getitem(ctx.state.w_string, space.wrap(group_start)))) + if ctx.at_end() or (not ignore and old_char != new_char) \ + or (ignore and ctx.state.lower(old_char) != ctx.state.lower(new_char)): + ctx.has_matched = ctx.NOT_MATCHED + return True + group_start += 1 + ctx.skip_char(1) + ctx.skip_code(2) + return True + +def op_groupref(space, ctx): + # match backreference + # + return general_op_groupref(space, ctx) + +def op_groupref_ignore(space, ctx): + # match backreference case-insensitive + # + return general_op_groupref(space, ctx, ignore=True) + +def op_groupref_exists(self, ctx): + # codeyes codeno ... + group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) + if group_start == -1 or group_end == -1 or group_end < group_start: + ctx.skip_code(ctx.peek_code(2) + 1) + else: + ctx.skip_code(3) + return True + opcode_dispatch_table = [ op_failure, op_success, op_any, op_any_all, @@ -412,12 +460,11 @@ None, #CALL, op_category, None, None, #CHARSET, BIGCHARSET, - None, None, None, #GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE, + op_groupref, op_groupref_exists, op_groupref_ignore, op_in, op_in_ignore, - None, #INFO, - None, #JUMP, + op_jump, op_jump, op_literal, op_literal_ignore, - None, #MARK, + op_mark, None, #MAX_UNTIL, None, #MIN_UNTIL, op_not_literal, op_not_literal_ignore, From ericvrp at codespeak.net Thu Aug 25 19:29:49 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 19:29:49 +0200 (CEST) Subject: [pypy-svn] r16533 - in pypy/dist/pypy/translator/llvm2: . demo test tool Message-ID: <20050825172949.E344227B4B@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 19:29:48 2005 New Revision: 16533 Modified: pypy/dist/pypy/translator/llvm2/demo/richards.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py Log: tests for strtod Modified: pypy/dist/pypy/translator/llvm2/demo/richards.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/richards.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/richards.py Thu Aug 25 19:29:48 2005 @@ -360,7 +360,7 @@ class Richards: - iterations = 25 + iterations = 2 def run(self): for i in xrange(self.iterations): Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 19:29:48 2005 @@ -182,12 +182,13 @@ j = os.path.join p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") + math_fns = 'acos asin atan ceil cos cosh exp fabs floor log log10 atan2 fmod ' math_fns += 'sin sinh sqrt tan tanh frexp modf pow hypot ldexp is_error' fns = [('ll_math_%s' % f) for f in math_fns.split()] - time_fns = "ll_time_time ll_time_clock ll_time_sleep ll_floattime" - fns += time_fns.split() - fns.append('ll_strtod_formatd') + fns += "ll_time_time ll_time_clock ll_time_sleep ll_floattime".split() + fns += "ll_strtod_parts_to_float ll_strtod_formatd".split() + return get_ll(open(p).read(), extern_dir, fns) def gen_llvm_source(self, func=None): Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Thu Aug 25 19:29:48 2005 @@ -225,5 +225,37 @@ assert f(0) == os.isatty(0) assert f(1) == os.isatty(1) assert f(2) == os.isatty(2) + +def test_rarith_parts_to_float(): + from pypy.rpython.rarithmetic import parts_to_float + parts = [ + ["" ,"1","" ,""], + ["-","1","" ,""], + ["-","1","5",""], + ["-","1","5","2"], + ["-","1","5","+2"], + ["-","1","5","-2"], + ] + val = [1.0, -1.0, -1.5, -1.5e2, -1.5e2, -1.5e-2] + def fn(i): + sign, beforept, afterpt, exponent = parts[i] + return parts_to_float(sign, beforept, afterpt, exponent) + f = compile_function(fn, [int]) + for i, v in enumerate(val): + assert f(i) == v + +def test_rarith_formatd(): + from pypy.rpython.rarithmetic import formatd + as_float = [ 0.0 , 1.5 , 2.0 ] + as_string = ["0.00", "1.50", "2.01"] + def fn(i): + if formatd("%.2f", as_float[i]) == as_string[i]: + return 1 + else: + return 0 + f = compile_function(fn, [int]) + for i, s in enumerate(as_string): + res = f(i) + assert res == 1 # end of tests taken from c backend Modified: pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py (original) +++ pypy/dist/pypy/translator/llvm2/tool/suggested_primitive.py Thu Aug 25 19:29:48 2005 @@ -3,12 +3,12 @@ import autopath from sets import Set -from pypy.rpython.module import ll_os, ll_os_path, ll_time, ll_math, ll_strtod #XXX keep this list up-to-date +from pypy.rpython.module import ll_os #XXX keep up to date from pypy.translator.llvm2.module.extfunction import extfunctions def main(): seen = Set() - for module in (ll_os, ll_os_path, ll_time, ll_math, ll_strtod): #XXX keep this list up-to-date too + for module in (ll_os,): #XXX keep this list up-to-date too suggested_primitives = Set( [func for func in dir(module) if func not in seen and getattr(module.__dict__[func], 'suggested_primitive', False)] ) seen |= suggested_primitives implemented_primitives = Set( [f[1:] for f in extfunctions.keys()] ) From arigo at codespeak.net Thu Aug 25 19:30:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 19:30:18 +0200 (CEST) Subject: [pypy-svn] r16534 - in pypy/dist/pypy/module/thread: . test Message-ID: <20050825173018.3C92427B4E@code1.codespeak.net> Author: arigo Date: Thu Aug 25 19:30:16 2005 New Revision: 16534 Modified: pypy/dist/pypy/module/thread/gil.py pypy/dist/pypy/module/thread/os_thread.py pypy/dist/pypy/module/thread/test/support.py pypy/dist/pypy/module/thread/test/test_thread.py Log: (pedronis, arigo) For the translated PyPy, we need to be extra super careful about making thread.start_new_thread() thread-safe (argh). Modified: pypy/dist/pypy/module/thread/gil.py ============================================================================== --- pypy/dist/pypy/module/thread/gil.py (original) +++ pypy/dist/pypy/module/thread/gil.py Thu Aug 25 19:30:16 2005 @@ -31,6 +31,7 @@ def yield_thread(self): """Notification that the current thread is between two bytecodes: release the GIL for a little while.""" - self.GIL.release() + GIL = self.GIL + GIL.release() # Other threads can run here - self.GIL.acquire(True) + GIL.acquire(True) Modified: pypy/dist/pypy/module/thread/os_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/os_thread.py (original) +++ pypy/dist/pypy/module/thread/os_thread.py Thu Aug 25 19:30:16 2005 @@ -11,26 +11,45 @@ import pypy.module.thread.rpython.exttable +THREAD_STARTUP_LOCK = thread.allocate_lock() + + class Bootstrapper: def bootstrap(self): - space = self.space - w_callable = self.w_callable - args = self.args + space = self.space + THREAD_STARTUP_LOCK.release() space.threadlocals.enter_thread(space) try: - try: - space.call_args(w_callable, args) - except OperationError, e: - if not e.match(space, space.w_SystemExit): - ident = thread.get_ident() - where = 'thread %d started by' % ident - e.write_unraisable(space, where, w_callable) - e.clear(space) + self.run() finally: + # release ownership of these objects before we release the GIL + self.args = None + self.w_callable = None + self.space = None + # at this point the thread should only have a reference to + # an empty 'self'. We hold the last reference to 'self'; indeed, + # the parent thread already forgot about it because the above + # enter_thread() must have blocked until long after the call to + # start_new_thread() below returned. + # (be careful of resetting *all* local variables to None here!) + # clean up space.threadlocals to remove the ExecutionContext # entry corresponding to the current thread space.threadlocals.leave_thread(space) + def run(self): + space = self.space + w_callable = self.w_callable + args = self.args + try: + space.call_args(w_callable, args) + except OperationError, e: + if not e.match(space, space.w_SystemExit): + ident = thread.get_ident() + where = 'thread %d started by' % ident + e.write_unraisable(space, where, w_callable) + e.clear(space) + def start_new_thread(space, w_callable, w_args, w_kwargs=NoneNotWrapped): """Start a new thread and return its identifier. The thread will call the @@ -47,7 +66,16 @@ boot.space = space boot.w_callable = w_callable boot.args = args + + THREAD_STARTUP_LOCK.acquire(True) + ident = thread.start_new_thread(Bootstrapper.bootstrap, (boot,)) + + # wait until the thread has really started and acquired a reference to + # 'boot'. + THREAD_STARTUP_LOCK.acquire(True) + THREAD_STARTUP_LOCK.release() + return space.wrap(ident) Modified: pypy/dist/pypy/module/thread/test/support.py ============================================================================== --- pypy/dist/pypy/module/thread/test/support.py (original) +++ pypy/dist/pypy/module/thread/test/support.py Thu Aug 25 19:30:16 2005 @@ -12,7 +12,7 @@ def waitfor(expr, timeout=10.0): limit = time.time() + timeout while time.time() <= limit: - time.sleep(0.005) + time.sleep(0.002) if expr(): return print '*** timed out ***' @@ -23,6 +23,6 @@ def busywait(t): limit = time.time() + t while time.time() <= limit: - time.sleep(0.005) + time.sleep(0.002) return busywait """) Modified: pypy/dist/pypy/module/thread/test/test_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/test/test_thread.py (original) +++ pypy/dist/pypy/module/thread/test/test_thread.py Thu Aug 25 19:30:16 2005 @@ -123,6 +123,6 @@ thread.start_new_thread(f, (i, done)) done_marker.append(done) for done in done_marker: - self.waitfor(lambda: done, timeout=20.0) + self.waitfor(lambda: done, timeout=30.0) assert done # see stderr for failures in threads assert sorted(lst) == range(120) From ericvrp at codespeak.net Thu Aug 25 19:30:36 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 19:30:36 +0200 (CEST) Subject: [pypy-svn] r16535 - pypy/dist/pypy/translator/llvm2/demo Message-ID: <20050825173036.7BAE527B4B@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 19:30:35 2005 New Revision: 16535 Modified: pypy/dist/pypy/translator/llvm2/demo/richards.py Log: oops Modified: pypy/dist/pypy/translator/llvm2/demo/richards.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/richards.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/richards.py Thu Aug 25 19:30:35 2005 @@ -360,7 +360,7 @@ class Richards: - iterations = 2 + iterations = 25 def run(self): for i in xrange(self.iterations): From arigo at codespeak.net Thu Aug 25 19:40:47 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 19:40:47 +0200 (CEST) Subject: [pypy-svn] r16536 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20050825174047.6E64827B4B@code1.codespeak.net> Author: arigo Date: Thu Aug 25 19:40:46 2005 New Revision: 16536 Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py Log: Found out how the Transformer handles docstring for functions and classes, and do the same thing for the module top-level. This gets rid of the first statement Discard(Const("docstring")) in docstrings, which is what should be expected according to the examples in the compiler package documentation. Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Thu Aug 25 19:40:46 2005 @@ -189,6 +189,12 @@ for node in nodelist: if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: self.com_append_stmt(stmts, node) + + if doc is not None: + assert isinstance(stmts[0], Discard) + assert isinstance(stmts[0].expr, Const) + del stmts[0] + return Module(doc, Stmt(stmts)) def eval_input(self, nodelist): From hpk at codespeak.net Thu Aug 25 19:44:27 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 19:44:27 +0200 (CEST) Subject: [pypy-svn] r16537 - in pypy/dist/lib-python: . modified-2.4.1/test/output Message-ID: <20050825174427.7E70027B4B@code1.codespeak.net> Author: hpk Date: Thu Aug 25 19:44:27 2005 New Revision: 16537 Added: pypy/dist/lib-python/modified-2.4.1/test/output/ pypy/dist/lib-python/modified-2.4.1/test/output/test_extcall Modified: pypy/dist/lib-python/conftest.py Log: - added the possibility to put modified output for outputtests in modified-2.4.1/test/output those are picked up when running compliancy tests via py.test - regenerated test_extcall output because we are basically correctly processing function arguments but produce different error messages mostly related to dictionary order and what not. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Aug 25 19:44:27 2005 @@ -328,6 +328,9 @@ return fn def getoutputpath(self): + p = modregrtestdir.join('output', self.basename).new(ext='') + if p.check(file=1): + return p p = regrtestdir.join('output', self.basename).new(ext='') if p.check(file=1): return p Added: pypy/dist/lib-python/modified-2.4.1/test/output/test_extcall ============================================================================== --- (empty file) +++ pypy/dist/lib-python/modified-2.4.1/test/output/test_extcall Thu Aug 25 19:44:27 2005 @@ -0,0 +1,112 @@ +test_extcall +() {} +(1,) {} +(1, 2) {} +(1, 2, 3) {} +(1, 2, 3, 4, 5) {} +(1, 2, 3, 4, 5) {} +(1, 2, 3, 4, 5) {} +(1, 2, 3) {'a': 4, 'b': 5} +(1, 2, 3, 4, 5) {'a': 6, 'b': 7} +(1, 2, 3, 6, 7) {'a': 8, 'b': 9, 'x': 4, 'y': 5} +TypeError: g() takes at least 1 argument (0 given) +TypeError: g() takes at least 1 argument (0 given) +TypeError: g() takes at least 1 argument (0 given) +1 () {} +1 (2,) {} +1 (2, 3) {} +1 (2, 3, 4, 5) {} +0 (1, 2) {} +0 (1, 2, 3) {} +1 () {'a': 1, 'b': 2, 'c': 3, 'd': 4} +{'a': 1, 'b': 2, 'c': 3} +{'a': 1, 'b': 2, 'c': 3} +g() got multiple values for keyword argument 'x' +got multiple values for keyword argument 'a' +keywords must be strings +h() got an unexpected keyword argument 'e' +object is not iter()-able +object is not iter()-able +object None is not callable +argument after ** must be a dictionary +argument after ** must be a dictionary +object None is not callable +got multiple values for keyword argument 'b' +3 512 True +3 +3 +za () {} -> za() takes exactly 1 argument (0 given) +za () {'a': 'aa'} -> ok za aa B D E V a +za () {'d': 'dd'} -> za() got an unexpected keyword argument 'd' +za () {'a': 'aa', 'd': 'dd'} -> za() got an unexpected keyword argument 'd' +za () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got 3 unexpected keyword arguments +za (1, 2) {} -> za() takes exactly 1 argument (2 given) +za (1, 2) {'a': 'aa'} -> za() got multiple values for keyword argument 'a' +za (1, 2) {'d': 'dd'} -> za() takes exactly 1 argument (3 given) +za (1, 2) {'a': 'aa', 'd': 'dd'} -> za() got multiple values for keyword argument 'a' +za (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got multiple values for keyword argument 'a' +za (1, 2, 3, 4, 5) {} -> za() takes exactly 1 argument (5 given) +za (1, 2, 3, 4, 5) {'a': 'aa'} -> za() got multiple values for keyword argument 'a' +za (1, 2, 3, 4, 5) {'d': 'dd'} -> za() takes exactly 1 argument (6 given) +za (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> za() got multiple values for keyword argument 'a' +za (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> za() got multiple values for keyword argument 'a' +zade () {} -> zade() takes at least 1 argument (0 given) +zade () {'a': 'aa'} -> ok zade aa B d e V a +zade () {'d': 'dd'} -> zade() takes at least 1 non-keyword argument (0 given) +zade () {'a': 'aa', 'd': 'dd'} -> ok zade aa B dd e V d +zade () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got an unexpected keyword argument 'b' +zade (1, 2) {} -> ok zade 1 B 2 e V e +zade (1, 2) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd' +zade (1, 2) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2, 3, 4, 5) {} -> zade() takes at most 3 arguments (5 given) +zade (1, 2, 3, 4, 5) {'a': 'aa'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2, 3, 4, 5) {'d': 'dd'} -> zade() got multiple values for keyword argument 'd' +zade (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zade() got multiple values for keyword argument 'a' +zade (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zade() got multiple values for keyword argument 'a' +zabk () {} -> zabk() takes exactly 2 non-keyword arguments (0 given) +zabk () {'a': 'aa'} -> zabk() takes exactly 2 non-keyword arguments (1 given) +zabk () {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (0 given) +zabk () {'a': 'aa', 'd': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (1 given) +zabk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabk aa bb D E V {'d': 'dd', 'e': 'ee'} +zabk (1, 2) {} -> ok zabk 1 2 D E V {} +zabk (1, 2) {'a': 'aa'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2) {'d': 'dd'} -> ok zabk 1 2 D E V {'d': 'dd'} +zabk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2, 3, 4, 5) {} -> zabk() takes exactly 2 non-keyword arguments (5 given) +zabk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabk() takes exactly 2 non-keyword arguments (5 given) +zabk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabk() got multiple values for keyword argument 'a' +zabk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabk() got multiple values for keyword argument 'a' +zabdv () {} -> zabdv() takes at least 2 arguments (0 given) +zabdv () {'a': 'aa'} -> zabdv() takes at least 2 non-keyword arguments (1 given) +zabdv () {'d': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (0 given) +zabdv () {'a': 'aa', 'd': 'dd'} -> zabdv() takes at least 2 non-keyword arguments (1 given) +zabdv () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got an unexpected keyword argument 'e' +zabdv (1, 2) {} -> ok zabdv 1 2 d E () e +zabdv (1, 2) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2) {'d': 'dd'} -> ok zabdv 1 2 dd E () d +zabdv (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2, 3, 4, 5) {} -> ok zabdv 1 2 3 E (4, 5) e +zabdv (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdv() got multiple values for keyword argument 'd' +zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdv() got multiple values for keyword argument 'a' +zabdv (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdv() got multiple values for keyword argument 'a' +zabdevk () {} -> zabdevk() takes at least 2 arguments (0 given) +zabdevk () {'a': 'aa'} -> zabdevk() takes at least 2 non-keyword arguments (1 given) +zabdevk () {'d': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (0 given) +zabdevk () {'a': 'aa', 'd': 'dd'} -> zabdevk() takes at least 2 non-keyword arguments (1 given) +zabdevk () {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> ok zabdevk aa bb dd ee () {} +zabdevk (1, 2) {} -> ok zabdevk 1 2 d e () {} +zabdevk (1, 2) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2) {'d': 'dd'} -> ok zabdevk 1 2 dd e () {} +zabdevk (1, 2) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2, 3, 4, 5) {} -> ok zabdevk 1 2 3 4 (5,) {} +zabdevk (1, 2, 3, 4, 5) {'a': 'aa'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2, 3, 4, 5) {'d': 'dd'} -> zabdevk() got multiple values for keyword argument 'd' +zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'd': 'dd'} -> zabdevk() got multiple values for keyword argument 'a' +zabdevk (1, 2, 3, 4, 5) {'a': 'aa', 'b': 'bb', 'd': 'dd', 'e': 'ee'} -> zabdevk() got multiple values for keyword argument 'a' From arigo at codespeak.net Thu Aug 25 19:53:03 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 19:53:03 +0200 (CEST) Subject: [pypy-svn] r16539 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050825175303.B35CA27B4B@code1.codespeak.net> Author: arigo Date: Thu Aug 25 19:53:02 2005 New Revision: 16539 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Log: 'snippet_transformer_bug.py' exposes a bug with the CPython compiler.transformer module, which we fixed. So we can't compare the output of CPython with ours any more for this test. Tentatively, I Hard-coded the expected result in test_sample.py. Modified: pypy/dist/pypy/interpreter/pyparser/test/test_samples.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_samples.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Thu Aug 25 19:53:02 2005 @@ -21,6 +21,11 @@ #"snippet_import_statements.py", "snippet_decorators.py", ] +REAL_EXPECTED_OUTPUT = { + # for snippets that show bugs of Python's compiler package + "snippet_transformer_bug.py": + "Module('This module does nothing', Stmt([Printnl([Const(1)], None)]))", + } def name(elt): @@ -96,11 +101,17 @@ # differences -- typically newlines at the end of the tree. print 'Comparing the ASTs of', testname transformer1 = PyPyTransformer() - transformer2 = PythonTransformer() ast_pypy = transformer1.compile_node(pypy_tuples) - ast_python = transformer2.compile_node(python_tuples) - repr_pypy = repr(ast_pypy) - repr_python = repr(ast_python) + repr_pypy = repr(ast_pypy) + + key = os.path.basename(testname) + if key not in REAL_EXPECTED_OUTPUT: + transformer2 = PythonTransformer() + ast_python = transformer2.compile_node(python_tuples) + repr_python = repr(ast_python) + else: + repr_python = REAL_EXPECTED_OUTPUT[key] + if GRAMMAR_MISMATCH: # XXX hack: # hide the more common difference between 2.3 and 2.4, which is From arigo at codespeak.net Thu Aug 25 20:13:15 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 20:13:15 +0200 (CEST) Subject: [pypy-svn] r16541 - in pypy/dist/pypy/rpython: . test Message-ID: <20050825181315.4929227B52@code1.codespeak.net> Author: arigo Date: Thu Aug 25 20:13:13 2005 New Revision: 16541 Modified: pypy/dist/pypy/rpython/rpbc.py pypy/dist/pypy/rpython/test/test_rpbc.py Log: Crashing on Void fields in MultipleFrozenPBCRepr objects. Fix and test. Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Thu Aug 25 20:13:13 2005 @@ -219,6 +219,8 @@ result = malloc(self.pbc_type, immortal=True) self.pbc_cache[pbc] = result for attr, (mangled_name, r_value) in self.llfieldmap.items(): + if r_value.lowleveltype == Void: + continue try: thisattrvalue = self.access_set.values[(pbc, attr)] except KeyError: Modified: pypy/dist/pypy/rpython/test/test_rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rpbc.py (original) +++ pypy/dist/pypy/rpython/test/test_rpbc.py Thu Aug 25 20:13:13 2005 @@ -823,3 +823,26 @@ except E: return None res = interpret(call, [0]) + +def test_multiple_pbc_with_void_attr(): + class A: + def _freeze_(self): + return True + a1 = A() + a2 = A() + unique = A() + unique.result = 42 + a1.value = unique + a2.value = unique + def g(a): + return a.value.result + def f(i): + if i == 1: + a = a1 + else: + a = a2 + return g(a) + res = interpret(f, [0]) + assert res == 42 + res = interpret(f, [1]) + assert res == 42 From hpk at codespeak.net Thu Aug 25 20:13:36 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 20:13:36 +0200 (CEST) Subject: [pypy-svn] r16542 - in pypy/dist/pypy/module/__builtin__: . test Message-ID: <20050825181336.7142E27B53@code1.codespeak.net> Author: hpk Date: Thu Aug 25 20:13:35 2005 New Revision: 16542 Modified: pypy/dist/pypy/module/__builtin__/app_misc.py pypy/dist/pypy/module/__builtin__/test/test_builtin.py Log: disallow interning of subclasses of str Modified: pypy/dist/pypy/module/__builtin__/app_misc.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/app_misc.py (original) +++ pypy/dist/pypy/module/__builtin__/app_misc.py Thu Aug 25 20:13:35 2005 @@ -6,11 +6,10 @@ _stringtable = {} def intern(s): # XXX CPython has also non-immortal interned strings - if not isinstance(s, str): + if not type(s) is str: raise TypeError("intern() argument 1 must be string.") return _stringtable.setdefault(s,s) - def reload(module): import imp, sys, errno Modified: pypy/dist/pypy/module/__builtin__/test/test_builtin.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/test/test_builtin.py (original) +++ pypy/dist/pypy/module/__builtin__/test/test_builtin.py Thu Aug 25 20:13:35 2005 @@ -17,6 +17,9 @@ def test_intern(self): raises(TypeError, intern) raises(TypeError, intern, 1) + class S(str): + pass + raises(TypeError, intern, S("hello")) s = "never interned before" s2 = intern(s) assert s == s2 From arigo at codespeak.net Thu Aug 25 20:13:53 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 20:13:53 +0200 (CEST) Subject: [pypy-svn] r16543 - pypy/dist/pypy/module/thread Message-ID: <20050825181353.CA5D027B53@code1.codespeak.net> Author: arigo Date: Thu Aug 25 20:13:52 2005 New Revision: 16543 Modified: pypy/dist/pypy/module/thread/os_thread.py Log: Oups. This line was propagating space-or-None annotations all over PyPy. That's an extreme un-optimization. Modified: pypy/dist/pypy/module/thread/os_thread.py ============================================================================== --- pypy/dist/pypy/module/thread/os_thread.py (original) +++ pypy/dist/pypy/module/thread/os_thread.py Thu Aug 25 20:13:52 2005 @@ -25,7 +25,6 @@ # release ownership of these objects before we release the GIL self.args = None self.w_callable = None - self.space = None # at this point the thread should only have a reference to # an empty 'self'. We hold the last reference to 'self'; indeed, # the parent thread already forgot about it because the above From ale at codespeak.net Thu Aug 25 20:35:44 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 25 Aug 2005 20:35:44 +0200 (CEST) Subject: [pypy-svn] r16544 - pypy/dist/pypy/lib Message-ID: <20050825183544.0A8CA27B4B@code1.codespeak.net> Author: ale Date: Thu Aug 25 20:35:42 2005 New Revision: 16544 Modified: pypy/dist/pypy/lib/_exceptions.py Log: (arre, ale) Changed the __str__ method of UnicodeEncodeError and UnicodeDecodeError to match CPython (and not to generate exceptions when trying to raise exceptions) Modified: pypy/dist/pypy/lib/_exceptions.py ============================================================================== --- pypy/dist/pypy/lib/_exceptions.py (original) +++ pypy/dist/pypy/lib/_exceptions.py Thu Aug 25 20:35:42 2005 @@ -354,16 +354,8 @@ raise TypeError('function takes exactly 5 arguments (%d given)'%argc) def __str__(self): - # this is a bad hack, please supply an implementation - res = ' '.join([ - 'object=' + str(getattr(self, 'object', None)), - 'end=' + str(getattr(self, 'end', None)), - 'encoding=' + str(getattr(self, 'encoding', None)), - 'args=' + str(getattr(self, 'args', None)), - 'start=' + str(getattr(self, 'start', None)), - 'reason=' + str(getattr(self, 'reason', None)), - ]) - return res + return "%r codec can't decode byte %x in position %d: %s"%(self.encoding, + ord(self.object[self.start]), self.start, self.reason) class TypeError(StandardError): """Inappropriate argument type.""" @@ -429,13 +421,5 @@ raise TypeError('function takes exactly 5 arguments (%d given)'%argc) def __str__(self): - # this is a bad hack, please supply an implementation - res = ' '.join([ - 'object=' + str(getattr(self, 'object', None)), - 'end=' + str(getattr(self, 'end', None)), - 'encoding=' + str(getattr(self, 'encoding', None)), - 'args=' + str(getattr(self, 'args', None)), - 'start=' + str(getattr(self, 'start', None)), - 'reason=' + str(getattr(self, 'reason', None)), - ]) - return res + return "%r codec can't encode character %r in position %d: %s"%(self.encoding, + self.object[self.start], self.start, self.reason) From arigo at codespeak.net Thu Aug 25 20:42:49 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 20:42:49 +0200 (CEST) Subject: [pypy-svn] r16546 - pypy/dist/pypy/objspace/std Message-ID: <20050825184249.57E0227B4E@code1.codespeak.net> Author: arigo Date: Thu Aug 25 20:42:48 2005 New Revision: 16546 Modified: pypy/dist/pypy/objspace/std/unicodetype.py Log: Renamed the 'obj' argument of unicode() to 'string', as in CPython. Modified: pypy/dist/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodetype.py (original) +++ pypy/dist/pypy/objspace/std/unicodetype.py Thu Aug 25 20:42:48 2005 @@ -94,8 +94,9 @@ return W_UnicodeObject(space, codelist) -def descr__new__(space, w_unicodetype, w_obj=None, w_encoding=None, w_errors=None): +def descr__new__(space, w_unicodetype, w_string=None, w_encoding=None, w_errors=None): from pypy.objspace.std.unicodeobject import W_UnicodeObject + w_obj = w_string w_obj_type = space.type(w_obj) if space.is_w(w_obj_type, space.w_unicode): From hpk at codespeak.net Thu Aug 25 20:44:29 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 20:44:29 +0200 (CEST) Subject: [pypy-svn] r16547 - pypy/dist/lib-python Message-ID: <20050825184429.334C227B53@code1.codespeak.net> Author: hpk Date: Thu Aug 25 20:44:28 2005 New Revision: 16547 Modified: pypy/dist/lib-python/conftest.py Log: reclassify test_user*.py as core tests because they test a lot of special methods. Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Thu Aug 25 20:44:28 2005 @@ -739,9 +739,9 @@ RegrTest('test_urllibnet.py', enabled=False), # try to understand failure!!! RegrTest('test_urlparse.py', enabled=True), - RegrTest('test_userdict.py', enabled=True), - RegrTest('test_userlist.py', enabled=True), - RegrTest('test_userstring.py', enabled=True), + RegrTest('test_userdict.py', enabled=True, core=True), + RegrTest('test_userlist.py', enabled=True, core=True), + RegrTest('test_userstring.py', enabled=True, core=True), RegrTest('test_uu.py', enabled=False), #rev 10840: 1 of 9 test fails From hpk at codespeak.net Thu Aug 25 20:57:29 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 20:57:29 +0200 (CEST) Subject: [pypy-svn] r16550 - pypy/dist/pypy/module/_sre_pypy Message-ID: <20050825185729.ADA0C27B57@code1.codespeak.net> Author: hpk Date: Thu Aug 25 20:57:29 2005 New Revision: 16550 Removed: pypy/dist/pypy/module/_sre_pypy/ Log: remove _sre_pypy now that we have our own (or rather Niklaus') sre implementation. From arigo at codespeak.net Thu Aug 25 21:08:47 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 25 Aug 2005 21:08:47 +0200 (CEST) Subject: [pypy-svn] r16552 - pypy/dist/pypy/interpreter Message-ID: <20050825190847.9CB8F27B58@code1.codespeak.net> Author: arigo Date: Thu Aug 25 21:08:46 2005 New Revision: 16552 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/pyopcode.py Log: In RPython we need a custom exception class to pass a message around. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Aug 25 21:08:46 2005 @@ -100,6 +100,12 @@ def _freeze_(self): return True +class UnpackValueError(ValueError): + def __init__(self, msg): + self.msg = msg + def __str__(self): + return self.msg + class ObjSpace(object): """Base class for the interpreter-level implementations of object spaces. http://codespeak.net/pypy/index.cgi?doc/objspace.html""" @@ -322,7 +328,7 @@ def unpackiterable(self, w_iterable, expected_length=-1): """Unpack an iterable object into a real (interpreter-level) list. - Raise a real ValueError if the length is wrong.""" + Raise a real (subclass of) ValueError if the length is wrong.""" w_iterator = self.iter(w_iterable) items = [] while True: @@ -333,7 +339,7 @@ raise break # done if expected_length != -1 and len(items) == expected_length: - raise ValueError, "too many values to unpack" + raise UnpackValueError("too many values to unpack") items.append(w_item) if expected_length != -1 and len(items) < expected_length: i = len(items) @@ -341,7 +347,8 @@ plural = "" else: plural = "s" - raise ValueError, "need more than %d value%s to unpack" % (i, plural) + raise UnpackValueError("need more than %d value%s to unpack" % + (i, plural)) return items def unpacktuple(self, w_tuple, expected_length=-1): @@ -349,8 +356,8 @@ Only use for bootstrapping or performance reasons.""" tuple_length = self.int_w(self.len(w_tuple)) if expected_length != -1 and tuple_length != expected_length: - raise ValueError, "got a tuple of length %d instead of %d" % ( - tuple_length, expected_length) + raise UnpackValueError("got a tuple of length %d instead of %d" % ( + tuple_length, expected_length)) items = [ self.getitem(w_tuple, self.wrap(i)) for i in range(tuple_length)] return items Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Thu Aug 25 21:08:46 2005 @@ -5,6 +5,7 @@ """ from pypy.interpreter.baseobjspace import OperationError, BaseWrappable +from pypy.interpreter.baseobjspace import UnpackValueError from pypy.interpreter import gateway, function from pypy.interpreter import pyframe, pytraceback from pypy.interpreter.miscutils import InitializedClass @@ -413,8 +414,8 @@ w_iterable = f.valuestack.pop() try: items = f.space.unpackiterable(w_iterable, itemcount) - except ValueError, e: - raise OperationError(f.space.w_ValueError, f.space.wrap(str(e))) + except UnpackValueError, e: + raise OperationError(f.space.w_ValueError, f.space.wrap(e.msg)) items.reverse() for item in items: f.valuestack.push(item) From nik at codespeak.net Thu Aug 25 21:36:02 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 21:36:02 +0200 (CEST) Subject: [pypy-svn] r16553 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050825193602.C031F27B5B@code1.codespeak.net> Author: nik Date: Thu Aug 25 21:36:01 2005 New Revision: 16553 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: came up with an RPython-compatible scheme to avoid recursion. moved the whole dispatcher loop to interp-level and implemented op_branch. there is a noticeable increase in speed but the a lot of tests fail now because of the remaining recursive opcodes. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Thu Aug 25 21:36:01 2005 @@ -21,6 +21,7 @@ '_State': 'interp_sre.make_state', '_MatchContext': 'interp_sre.make_context', '_RepeatContext': 'interp_sre.make_repeat_context', + '_match': 'interp_sre.match', '_opcode_dispatch': 'interp_sre.opcode_dispatch', '_opcode_is_at_interplevel': 'interp_sre.opcode_is_at_interplevel', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 21:36:01 2005 @@ -36,7 +36,7 @@ regular expression, return a corresponding MatchObject instance. Return None if the string does not match the pattern.""" state = _sre._State(string, pos, endpos, self.flags) - if match(state, self._code): + if _sre._match(state, self._code): return SRE_Match(self, state) else: return None @@ -327,7 +327,7 @@ while string_position <= state.end: state.reset() state.start = state.string_position = string_position - if match(state, pattern_codes): + if _sre._match(state, pattern_codes): return True string_position += 1 return False @@ -362,7 +362,7 @@ - prefix_len + prefix_skip if flags & SRE_INFO_LITERAL: return True # matched all of pure literal pattern - if match(state, pattern_codes[2 * prefix_skip:]): + if _sre._match(state, pattern_codes[2 * prefix_skip:]): return True i = overlap[i] break @@ -454,31 +454,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def op_branch(self, ctx): - # alternation - # <0=skip> code ... - #self._log(ctx, "BRANCH") - ctx.state.marks_push() - ctx.skip_code(1) - current_branch_length = ctx.peek_code(0) - while current_branch_length: - # The following tries to shortcut branches starting with a - # (unmatched) literal. _sre.c also shortcuts charsets here. - if not (ctx.peek_code(1) == OPCODES["literal"] and \ - (ctx.at_end() or ctx.peek_code(2) != ord(ctx.peek_char()))): - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(1) - yield False - if child_context.has_matched == MATCHED: - ctx.has_matched = MATCHED - yield True - ctx.state.marks_pop_keep() - ctx.skip_code(current_branch_length) - current_branch_length = ctx.peek_code(0) - ctx.state.marks_pop_discard() - ctx.has_matched = NOT_MATCHED - yield True - def op_repeat_one(self, ctx): # match repeated sequence (maximizing). # this operator only works if the repeated item is exactly one character Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 21:36:01 2005 @@ -56,7 +56,7 @@ self.marks = [] self.lastindex = -1 self.marks_stack = [] - self.w_context_stack = self.space.newlist([]) + self.context_stack = [] self.w_repeat = self.space.w_None def set_mark(self, mark_nr, position): @@ -135,7 +135,6 @@ string_position = interp_attrproperty_int("string_position", W_State), pos = interp_attrproperty("pos", W_State), lastindex = interp_attrproperty("lastindex", W_State), - context_stack = interp_attrproperty_w("w_context_stack", W_State), repeat = interp_attrproperty_obj_w("w_repeat", W_State), reset = interp2app(W_State.reset), create_regs = interp2app(W_State.create_regs), @@ -163,18 +162,31 @@ self.string_position = w_state.string_position self.code_position = 0 self.has_matched = self.UNDECIDED + self.backup = [] + self.resume_at_opcode = -1 - def push_new_context(self, w_pattern_offset): + def push_new_context(self, pattern_offset): """Creates a new child context of this context and pushes it on the stack. pattern_offset is the offset off the current code position to start interpreting from.""" - pattern_offset = self.space.int_w(w_pattern_offset) pattern_codes_w = self.pattern_codes_w[self.code_position + pattern_offset:] w_child_context = self.space.wrap(W_MatchContext(self.space, self.state, self.space.newlist(pattern_codes_w))) - self.space.call_method(self.state.w_context_stack, "append", w_child_context) + self.state.context_stack.append(w_child_context) + self.child_context = w_child_context return w_child_context + def is_resumed(self): + return self.resume_at_opcode > -1 + + def backup_value(self, value): + self.backup.append(value) + + def restore_values(self): + values = self.backup + self.backup = [] + return values + def peek_char(self, w_peek=0): # XXX temporary hack if w_peek == 0: @@ -239,7 +251,7 @@ pattern_codes = interp_attrproperty_list_w("pattern_codes_w", W_MatchContext), code_position = interp_attrproperty_int("code_position", W_MatchContext), has_matched = interp_attrproperty_int("has_matched", W_MatchContext), - push_new_context = interp2app(W_MatchContext.push_new_context), + #push_new_context = interp2app(W_MatchContext.push_new_context), peek_char = interp2app(W_MatchContext.peek_char), skip_char = interp2app(W_MatchContext.w_skip_char), remaining_chars = interp2app(W_MatchContext.w_remaining_chars), @@ -268,7 +280,47 @@ last_position = interp_attrproperty_obj_w("w_last_position", W_RepeatContext), ) -#### Opcode dispatch +#### Main opcode dispatch loop + +def match(space, w_state, w_pattern_codes): + # Optimization: Check string length. pattern_codes[3] contains the + # minimum length for a string to possibly match. + # XXX disabled for now + #if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: + # if state.end - state.string_position < pattern_codes[3]: + # return False + state = w_state + state.context_stack.append(W_MatchContext(space, state, w_pattern_codes)) + has_matched = W_MatchContext.UNDECIDED + while len(state.context_stack) > 0: + context = state.context_stack[-1] + if context.has_matched == context.UNDECIDED: + has_matched = dispatch_loop(space, context) + else: + has_matched = context.has_matched + if has_matched != context.UNDECIDED: # don't pop if context isn't done + state.context_stack.pop() + return space.newbool(has_matched == context.MATCHED) + +def dispatch_loop(space, context): + """Returns MATCHED if the current context matches, NOT_MATCHED if it doesn't + and UNDECIDED if matching is not finished, ie must be resumed after child + contexts have been matched.""" + while context.remaining_codes() > 0 and context.has_matched == context.UNDECIDED: + if context.is_resumed(): + opcode = context.resume_at_opcode + else: + opcode = context.peek_code() + #try: + has_finished = opcode_dispatch_table[opcode](space, context) + #except IndexError: + # raise RuntimeError("Internal re error. Unknown opcode: %s" % opcode) + if not has_finished: + context.resume_at_opcode = opcode + return context.UNDECIDED + if context.has_matched == context.UNDECIDED: + context.has_matched = context.NOT_MATCHED + return context.has_matched def opcode_dispatch(space, w_opcode, w_context): opcode = space.int_w(w_opcode) @@ -399,6 +451,30 @@ general_op_in(space, ctx, ignore=True) return True +def op_branch(space, ctx): + # alternation + # <0=skip> code ... + if ctx.is_resumed(): + last_branch_length = ctx.restore_values()[0] + if ctx.child_context.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + ctx.state.marks_pop_keep() + ctx.skip_code(last_branch_length) + current_branch_length = ctx.peek_code(0) + else: + ctx.state.marks_push() + ctx.skip_code(1) + current_branch_length = ctx.peek_code(0) + if current_branch_length: + ctx.state.string_position = ctx.string_position + ctx.push_new_context(1) + ctx.backup_value(current_branch_length) + return False + ctx.state.marks_pop_discard() + ctx.has_matched = ctx.NOT_MATCHED + return True + def op_jump(space, ctx): # jump forward # / @@ -456,7 +532,7 @@ op_any, op_any_all, None, None, #ASSERT, ASSERT_NOT, op_at, - None, #BRANCH, + op_branch, None, #CALL, op_category, None, None, #CHARSET, BIGCHARSET, Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== From rxe at codespeak.net Thu Aug 25 21:44:04 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 21:44:04 +0200 (CEST) Subject: [pypy-svn] r16554 - in pypy/dist/pypy/translator/llvm2: . module test Message-ID: <20050825194404.823CC27B5D@code1.codespeak.net> Author: rxe Date: Thu Aug 25 21:44:03 2005 New Revision: 16554 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Log: Checking in temp - see next msg for useful info. Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Thu Aug 25 21:44:03 2005 @@ -74,12 +74,15 @@ else: optimization_switches = SIMPLE_OPTIMIZATION_SWITCHES - cmds = ["llvm-as %s.ll" % b] + #XXX outcommented for testing merging extern.ll in main .ll file + #cmds = ["llvm-as %s.ll" % b] + # + #bcfile = dirpath.join("externs", "externs_linked.bc") + #cmds.append("llvm-link %s.bc %s -o %s_all.bc" % (b, str(bcfile), b)) + #ball = str(dirpath.join('%s_all.bc' % b)) + #cmds.append("opt %s %s -f -o %s.bc" % (OPTIMIZATION_SWITCHES, ball, b)) - bcfile = dirpath.join("externs", "externs_linked.bc") - cmds.append("llvm-link %s.bc %s -o %s_all.bc" % (b, str(bcfile), b)) - ball = str(dirpath.join('%s_all.bc' % b)) - cmds.append("opt %s %s -f -o %s.bc" % (OPTIMIZATION_SWITCHES, ball, b)) + cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, OPTIMIZATION_SWITCHES, b)] if False and sys.maxint == 2147483647: #32 bit platform cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) @@ -91,8 +94,8 @@ #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)) if exe_name: - cmds.append("gcc %s.c -c -O2 -fomit-frame-pointer" % (b,)) - cmds.append("gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) + cmds.append("gcc -g %s.c -c -O2 -fomit-frame-pointer" % (b,)) + cmds.append("gcc -g %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) source_files.append("%s.c" % b) try: Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 21:44:03 2005 @@ -55,11 +55,12 @@ if comment >= 0: line = line[:comment] line = line.rstrip() - #if line[-1:] == '{': - # returntype, s = line.split(' ', 1) - # funcname , s = s.split('(', 1) - # funcnames[funcname] = True - # line = '%s %s %s' % ("", DEFAULT_CCONV, line,) + if line[-1:] == '{': + returntype, s = line.split(' ', 1) + funcname , s = s.split('(', 1) + funcnames[funcname] = True + assert line.find("internal") == -1 + line = '%s %s %s' % ("", DEFAULT_CCONV, line,) ll_lines.append(line) #patch calls to function that we just declared fastcc @@ -83,28 +84,31 @@ ll_lines2.append(line) llcode = '\n'.join(ll_lines2) + return llcode.split('implementation') #XXX testing - # create file - llfilename = extern_dir.join("externs").new(ext='.ll') - f = open(str(llfilename), 'w') - f.write(llcode) - f.close() - + #XXX temp disabled + # + ## create file + #llfilename = extern_dir.join("externs").new(ext='.ll') + #f = open(str(llfilename), 'w') + #f.write(llcode) + #f.close() + # # create bytecode - os.chdir(str(extern_dir)) - cmdexec('llvm-as externs.ll') - bcfilename = extern_dir.join("externs").new(ext='.bc') - if functions: - for func in functions: - # extract - cmdexec('llvm-extract -func %s -o %s.bc externs.bc' % (func, func)) - - # link all the ll files - functions_bcs = ' '.join(['%s.bc' % func for func in functions]) - cmdexec('llvm-link -o externs_linked.bc ' + functions_bcs) - bcfilename = extern_dir.join("externs_linked").new(ext='.bc') - - return bcfilename + #os.chdir(str(extern_dir)) + #cmdexec('llvm-as externs.ll') + #bcfilename = extern_dir.join("externs").new(ext='.bc') + #if functions: + # for func in functions: + # # extract + # cmdexec('llvm-extract -func %s -o %s.bc externs.bc' % (func, func)) + # + # # link all the ll files + # functions_bcs = ' '.join(['%s.bc' % func for func in functions]) + # cmdexec('llvm-link -o externs_linked.bc ' + functions_bcs) + # bcfilename = extern_dir.join("externs_linked").new(ext='.bc') + # + #return bcfilename class GenLLVM(object): @@ -214,7 +218,7 @@ self.translator.rtyper.specialize_more_blocks() self.db.setup_all() - self.generate_llfile(extern_decls) + lldeclarations, llimplementation = self.generate_llfile(extern_decls) #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) @@ -235,6 +239,10 @@ comment = codewriter.comment nl = codewriter.newline + nl(); comment("EXTERNAL FUNCTION DECLARATIONS") ; nl() + for s in lldeclarations.split('\n'): + codewriter.append(s) + nl(); comment("Type Declarations"); nl() for c_name, obj in extern_decls: @@ -327,7 +335,10 @@ if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy extfuncnode.ExternalFuncNode.used_external_functions['%main'] = True - extfuncnode.ExternalFuncNode.used_external_functions['%RPyString_FromString'] = True + for f in "prepare_and_raise_OverflowError prepare_and_raise_ValueError "\ + "prepare_and_raise_ZeroDivisionError prepare_and_raise_IOError "\ + "RPyString_FromString RPyString_AsString RPyString_Size".split(): + extfuncnode.ExternalFuncNode.used_external_functions["%" + f] = True if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() depdone = {} @@ -347,6 +358,10 @@ codewriter.append(extfunc) depdone[dep] = True + nl(); comment("EXTERNAL FUNCTION IMPLEMENTATION") ; nl() + for s in llimplementation.split('\n'): + codewriter.append(s) + comment("End of file") ; nl() if self.debug: print 'gen_llvm_source return) ' + time.ctime() return filename @@ -355,7 +370,7 @@ filename, really_compile=True, standalone=False, - optimize=False, + optimize=True, exe_name=None): if not llvm_is_on_path(): Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 21:44:03 2005 @@ -18,7 +18,7 @@ struct RPyMODF_RESULT *ll_modf_result__Float_Float(double, double); char *RPyString_AsString(struct RPyString*); -int RPyString_Size(struct RPyString_Size*); +int RPyString_Size(struct RPyString*); struct RPyString *RPyString_FromString(char *); void prepare_and_raise_OverflowError(char *); @@ -340,8 +340,7 @@ #endif /* MS_WINDOWS */ #endif /* HAVE_FTIME */ -static double -ll_floattime(void) +double ll_floattime(void) { /* There are three ways to get the time: (1) gettimeofday() -- resolution in microseconds @@ -381,6 +380,7 @@ return ll_floattime(); } + double ll_strtod_parts_to_float(struct RPyString *sign, struct RPyString *beforept, struct RPyString *afterpt, @@ -392,18 +392,25 @@ int decimal_point_len; double x; char *last; - char *expo = RPyString_AsString(exponent); int buf_size; char *s; + char *expo = NULL; + + fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1111111111XXXXXX hello\n"); + + expo = RPyString_AsString(exponent); + fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXX222222222XXXXXXXXXXXXXXXXXX hello\n"); if (*expo == '\0') { expo = "0"; } + fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX33333XXXXXXXXXXXXX hello\n"); locale_data = localeconv(); decimal_point = locale_data->decimal_point; decimal_point_len = strlen(decimal_point); + fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX44444XXXXXXXX hello\n"); buf_size = RPyString_Size(sign) + RPyString_Size(beforept) + decimal_point_len + @@ -412,6 +419,7 @@ strlen(expo) + 1 /* asciiz */ ; + fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5555XXXX hello\n"); s = malloc(buf_size); strcpy(s, RPyString_AsString(sign)); @@ -421,20 +429,26 @@ strcat(s, "e"); strcat(s, expo); + fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6666 hello\n"); last = s + (buf_size-1); x = strtod(s, &fail_pos); errno = 0; - free(s); + fprintf(stderr, "XXXXXXXXX77777777777777777777799999999999999999999999hello\n"); if (fail_pos > last) fail_pos = last; + fprintf(stderr, "XXXXX888888888888888888888888999999999999999999999999hello\n"); if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { + free(s); prepare_and_raise_ValueError("invalid float literal"); return -1.0; } + fprintf(stderr, "XXXXXXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9999999999999hello\n"); if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ x = strtod(s, NULL); errno = 0; } + fprintf(stderr, "XXXXXXXXXXXX99999999999999999999999999999999999999999hello\n"); + free(s); return x; } @@ -443,6 +457,7 @@ char buffer[120]; /* this should be enough, from PyString_Format code */ int buflen = 120; int res; + res = snprintf(buffer, buflen, RPyString_AsString(fmt), x); if (res <= 0 || res >= buflen) { strcpy(buffer, "??.?"); /* should not occur */ Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 21:44:03 2005 @@ -3,7 +3,7 @@ declare ccc double %pow(double, double) declare ccc double %fmod(double, double) declare ccc int %puts(sbyte*) -declare ccc int %strlen(sbyte*) +declare ccc uint %strlen(sbyte*) declare ccc int %strcmp(sbyte*, sbyte*) declare ccc sbyte* %memset(sbyte*, int, uint) @@ -43,7 +43,7 @@ internal fastcc int %RPyString_Size(%RPyString* %structstring) { %sizeptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %size = load int* %sizeptr - return %size + ret int %size } @@ -51,7 +51,8 @@ extfunctions["%RPyString_FromString"] = ((), """ internal fastcc %RPyString* %RPyString_FromString(sbyte* %s) { - %len = call ccc int %strlen(sbyte* %s) + %lenu = call ccc uint %strlen(sbyte* %s) + %len = cast uint %lenu to int %rpy = call fastcc %RPyString* %RPyString_New__Signed(int %len) %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* Modified: pypy/dist/pypy/translator/llvm2/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm2/test/test_extfunc.py Thu Aug 25 21:44:03 2005 @@ -247,15 +247,11 @@ def test_rarith_formatd(): from pypy.rpython.rarithmetic import formatd as_float = [ 0.0 , 1.5 , 2.0 ] - as_string = ["0.00", "1.50", "2.01"] + as_string = ["0.00", "1.50", "2.00"] def fn(i): - if formatd("%.2f", as_float[i]) == as_string[i]: - return 1 - else: - return 0 + return formatd("%.2f", as_float[i]) == as_string[i] f = compile_function(fn, [int]) for i, s in enumerate(as_string): - res = f(i) - assert res == 1 + assert f(i) # end of tests taken from c backend From ericvrp at codespeak.net Thu Aug 25 22:00:31 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 25 Aug 2005 22:00:31 +0200 (CEST) Subject: [pypy-svn] r16555 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050825200031.168D327B53@code1.codespeak.net> Author: ericvrp Date: Thu Aug 25 22:00:30 2005 New Revision: 16555 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/genexterns.c Log: generate externals multiple times again Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Thu Aug 25 22:00:30 2005 @@ -159,10 +159,12 @@ def generate_llfile(self, extern_decls): - extern_dir = udir.join("externs") - if extern_dir.check(dir=1): - return - extern_dir.mkdir() + #XXX outcommented because we are not puting files here + #extern_dir = udir.join("externs") + #if extern_dir.check(dir=1): + # return + #extern_dir.mkdir() + extern_dir = None genllcode = "" Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 22:00:30 2005 @@ -396,21 +396,16 @@ char *s; char *expo = NULL; - fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1111111111XXXXXX hello\n"); - expo = RPyString_AsString(exponent); - fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXX222222222XXXXXXXXXXXXXXXXXX hello\n"); if (*expo == '\0') { expo = "0"; } - fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX33333XXXXXXXXXXXXX hello\n"); locale_data = localeconv(); decimal_point = locale_data->decimal_point; decimal_point_len = strlen(decimal_point); - fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX44444XXXXXXXX hello\n"); buf_size = RPyString_Size(sign) + RPyString_Size(beforept) + decimal_point_len + @@ -419,7 +414,6 @@ strlen(expo) + 1 /* asciiz */ ; - fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5555XXXX hello\n"); s = malloc(buf_size); strcpy(s, RPyString_AsString(sign)); @@ -429,25 +423,20 @@ strcat(s, "e"); strcat(s, expo); - fprintf(stderr, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6666 hello\n"); last = s + (buf_size-1); x = strtod(s, &fail_pos); errno = 0; - fprintf(stderr, "XXXXXXXXX77777777777777777777799999999999999999999999hello\n"); if (fail_pos > last) fail_pos = last; - fprintf(stderr, "XXXXX888888888888888888888888999999999999999999999999hello\n"); if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { - free(s); + free(s); prepare_and_raise_ValueError("invalid float literal"); return -1.0; } - fprintf(stderr, "XXXXXXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9999999999999hello\n"); if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ x = strtod(s, NULL); errno = 0; } - fprintf(stderr, "XXXXXXXXXXXX99999999999999999999999999999999999999999hello\n"); free(s); return x; } From nik at codespeak.net Thu Aug 25 22:05:20 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Thu, 25 Aug 2005 22:05:20 +0200 (CEST) Subject: [pypy-svn] r16556 - pypy/dist/pypy/module/_sre Message-ID: <20050825200520.0278D27B53@code1.codespeak.net> Author: nik Date: Thu Aug 25 22:05:19 2005 New Revision: 16556 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: implemented op_repeat_one with new scheme Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Thu Aug 25 22:05:19 2005 @@ -454,69 +454,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def op_repeat_one(self, ctx): - # match repeated sequence (maximizing). - # this operator only works if the repeated item is exactly one character - # wide, and we're not already collecting backtracking points. - # <1=min> <2=max> item tail - mincount = ctx.peek_code(2) - maxcount = ctx.peek_code(3) - #self._log(ctx, "REPEAT_ONE", mincount, maxcount) - - if ctx.remaining_chars() < mincount: - ctx.has_matched = NOT_MATCHED - yield True - ctx.state.string_position = ctx.string_position - count = self.count_repetitions(ctx, maxcount) - ctx.skip_char(count) - if count < mincount: - ctx.has_matched = NOT_MATCHED - yield True - if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: - # tail is empty. we're finished - ctx.state.string_position = ctx.string_position - ctx.has_matched = MATCHED - yield True - - ctx.state.marks_push() - if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["literal"]: - # Special case: Tail starts with a literal. Skip positions where - # the rest of the pattern cannot possibly match. - char = ctx.peek_code(ctx.peek_code(1) + 2) - while True: - while count >= mincount and \ - (ctx.at_end() or ord(ctx.peek_char()) != char): - ctx.skip_char(-1) - count -= 1 - if count < mincount: - break - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(ctx.peek_code(1) + 1) - yield False - if child_context.has_matched == MATCHED: - ctx.has_matched = MATCHED - yield True - ctx.skip_char(-1) - count -= 1 - ctx.state.marks_pop_keep() - - else: - # General case: backtracking - while count >= mincount: - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(ctx.peek_code(1) + 1) - yield False - if child_context.has_matched == MATCHED: - ctx.has_matched = MATCHED - yield True - ctx.skip_char(-1) - count -= 1 - ctx.state.marks_pop_keep() - - ctx.state.marks_pop_discard() - ctx.has_matched = NOT_MATCHED - yield True - def op_min_repeat_one(self, ctx): # match repeated sequence (minimizing) # <1=min> <2=max> item tail Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Thu Aug 25 22:05:19 2005 @@ -13,6 +13,7 @@ # XXX can we import those safely from sre_constants? SRE_FLAG_LOCALE = 4 # honour system locale SRE_FLAG_UNICODE = 32 # use unicode locale +MAXREPEAT = 65535 def getlower(space, w_char_ord, w_flags): char_ord = space.int_w(w_char_ord) @@ -454,18 +455,18 @@ def op_branch(space, ctx): # alternation # <0=skip> code ... - if ctx.is_resumed(): - last_branch_length = ctx.restore_values()[0] + if not ctx.is_resumed(): + ctx.state.marks_push() + ctx.skip_code(1) + current_branch_length = ctx.peek_code(0) + else: if ctx.child_context.has_matched == ctx.MATCHED: ctx.has_matched = ctx.MATCHED return True ctx.state.marks_pop_keep() + last_branch_length = ctx.restore_values()[0] ctx.skip_code(last_branch_length) current_branch_length = ctx.peek_code(0) - else: - ctx.state.marks_push() - ctx.skip_code(1) - current_branch_length = ctx.peek_code(0) if current_branch_length: ctx.state.string_position = ctx.string_position ctx.push_new_context(1) @@ -475,6 +476,58 @@ ctx.has_matched = ctx.NOT_MATCHED return True +def op_repeat_one(space, ctx): + # match repeated sequence (maximizing). + # this operator only works if the repeated item is exactly one character + # wide, and we're not already collecting backtracking points. + # <1=min> <2=max> item tail + + # Case 1: First entry point + if not ctx.is_resumed(): + mincount = ctx.peek_code(2) + maxcount = ctx.peek_code(3) + if ctx.remaining_chars() < mincount: + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.state.string_position = ctx.string_position + count = count_repetitions(space, ctx, maxcount) + ctx.skip_char(count) + if count < mincount: + ctx.has_matched = ctx.NOT_MATCHED + return True + if ctx.peek_code(ctx.peek_code(1) + 1) == 1: # 1 == OPCODES["success"] + # tail is empty. we're finished + ctx.state.string_position = ctx.string_position + ctx.has_matched = ctx.MATCHED + return True + ctx.state.marks_push() + # XXX literal optimization missing here + + # Case 2: Repetition is resumed (aka backtracked) + else: + if ctx.child_context.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + values = ctx.restore_values() + mincount = values[0] + count = values[1] + ctx.skip_char(-1) + count -= 1 + ctx.state.marks_pop_keep() + + # Initialize the actual backtracking + if count >= mincount: + ctx.state.string_position = ctx.string_position + ctx.push_new_context(ctx.peek_code(1) + 1) + ctx.backup_value(mincount) + ctx.backup_value(count) + return False + + # Backtracking failed + ctx.state.marks_pop_discard() + ctx.has_matched = ctx.NOT_MATCHED + return True + def op_jump(space, ctx): # jump forward # / @@ -527,6 +580,34 @@ ctx.skip_code(3) return True +def count_repetitions(space, ctx, maxcount): + """Returns the number of repetitions of a single item, starting from the + current string position. The code pointer is expected to point to a + REPEAT_ONE operation (with the repeated 4 ahead).""" + count = 0 + real_maxcount = ctx.state.end - ctx.string_position + if maxcount < real_maxcount and maxcount != MAXREPEAT: + real_maxcount = maxcount + # XXX could special case every single character pattern here, as in C. + # This is a general solution, a bit hackisch, but works and should be + # efficient. + code_position = ctx.code_position + string_position = ctx.string_position + ctx.skip_code(4) + reset_position = ctx.code_position + while count < real_maxcount: + # this works because the single character pattern is followed by + # a success opcode + ctx.code_position = reset_position + opcode_dispatch_table[ctx.peek_code()](space, ctx) + if ctx.has_matched == ctx.NOT_MATCHED: + break + count += 1 + ctx.has_matched = ctx.UNDECIDED + ctx.code_position = code_position + ctx.string_position = string_position + return count + opcode_dispatch_table = [ op_failure, op_success, op_any, op_any_all, @@ -547,7 +628,7 @@ None, #NEGATE, None, #RANGE, None, #REPEAT, - None, #REPEAT_ONE, + op_repeat_one, None, #SUBPATTERN, None, #MIN_REPEAT_ONE ] From hpk at codespeak.net Thu Aug 25 22:18:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 25 Aug 2005 22:18:06 +0200 (CEST) Subject: [pypy-svn] r16558 - pypy/dist/pypy/lib/_stablecompiler Message-ID: <20050825201806.7312A27B54@code1.codespeak.net> Author: hpk Date: Thu Aug 25 22:18:06 2005 New Revision: 16558 Modified: pypy/dist/pypy/lib/_stablecompiler/consts.py pypy/dist/pypy/lib/_stablecompiler/pyassem.py pypy/dist/pypy/lib/_stablecompiler/pycodegen.py pypy/dist/pypy/lib/_stablecompiler/symbols.py pypy/dist/pypy/lib/_stablecompiler/transformer.py Log: merge of pypy/interpreter/stablecompiler changes to pypy/lib/_stablecompiler with svn merge -r 15452:16555 http://codespeak.net/svn/pypy/dist/pypy/interpreter/stablecompiler while being in the _stablecompiler directory. resolved conflicts that were mostly related to the trailing import sections. Modified: pypy/dist/pypy/lib/_stablecompiler/consts.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/consts.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/consts.py Thu Aug 25 22:18:06 2005 @@ -8,6 +8,7 @@ SC_FREE = 3 SC_CELL = 4 SC_UNKNOWN = 5 +SC_DEFAULT = 6 CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 Modified: pypy/dist/pypy/lib/_stablecompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pyassem.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pyassem.py Thu Aug 25 22:18:06 2005 @@ -316,7 +316,8 @@ class PyFlowGraph(FlowGraph): super_init = FlowGraph.__init__ - def __init__(self, name, filename, args=(), optimized=0, klass=None): + def __init__(self, name, filename, args=(), optimized=0, + klass=None, newlocals=0): self.super_init() self.name = name self.filename = filename @@ -324,10 +325,11 @@ self.args = args # XXX self.argcount = getArgCount(args) self.klass = klass + self.flags = 0 if optimized: - self.flags = CO_OPTIMIZED | CO_NEWLOCALS - else: - self.flags = 0 + self.flags |= CO_OPTIMIZED + if newlocals: + self.flags |= CO_NEWLOCALS self.consts = [] self.names = [] # Free variables found by the symbol table scan, including Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Thu Aug 25 22:18:06 2005 @@ -10,7 +10,7 @@ from transformer import parse from visitor import walk import pyassem, misc, future, symbols -from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL +from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_DEFAULT from consts import CO_VARARGS, CO_VARKEYWORDS, \ CO_NEWLOCALS, CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION from pyassem import TupleArg @@ -195,6 +195,9 @@ defined. """ + scopeambiguity = False + parentscopeambiguity = False + optimized = 0 # is namespace access optimized? __initialized = None class_name = None # provide default for instance variable @@ -267,9 +270,18 @@ self._nameOp('STORE', name) def loadName(self, name): + if (self.scope.nested and self.scopeambiguity and + name in self.scope.hasbeenfree): + raise SyntaxError("cannot reference variable '%s' because " + "of ambiguity between " + "scopes" % name) self._nameOp('LOAD', name) def delName(self, name): + scope = self.scope.check_name(name) + if scope == SC_CELL: + raise SyntaxError("can not delete variable '%s' " + "referenced in nested scope" % name) self._nameOp('DELETE', name) def _nameOp(self, prefix, name): @@ -281,12 +293,14 @@ else: self.emit(prefix + '_FAST', name) elif scope == SC_GLOBAL: - if not self.optimized: - self.emit(prefix + '_NAME', name) - else: - self.emit(prefix + '_GLOBAL', name) + self.emit(prefix + '_GLOBAL', name) elif scope == SC_FREE or scope == SC_CELL: self.emit(prefix + '_DEREF', name) + elif scope == SC_DEFAULT: + if self.optimized and self.localsfullyknown: + self.emit(prefix + '_GLOBAL', name) + else: + self.emit(prefix + '_NAME', name) else: raise RuntimeError, "unsupported scope for var %s: %d" % \ (name, scope) @@ -376,7 +390,8 @@ ndecorators = 0 gen = self.FunctionGen(node, self.scopes, isLambda, - self.class_name, self.get_module()) + self.class_name, self.get_module(), + parentscopeambiguity = self.scopeambiguity or self.parentscopeambiguity) walk(node.code, gen) gen.finish() self.set_lineno(node) @@ -397,7 +412,8 @@ def visitClass(self, node): gen = self.ClassGen(node, self.scopes, - self.get_module()) + self.get_module(), + parentscopeambiguity = self.scopeambiguity or self.parentscopeambiguity) walk(node.code, gen) gen.finish() self.set_lineno(node) @@ -631,7 +647,8 @@ def visitGenExpr(self, node): gen = GenExprCodeGenerator(node, self.scopes, self.class_name, - self.get_module()) + self.get_module(), + parentscopeambiguity=self.scopeambiguity or self.parentscopeambiguity) walk(node.code, gen) gen.finish() self.set_lineno(node) @@ -811,6 +828,11 @@ # misc def visitDiscard(self, node): + # Important: this function is overridden in InteractiveCodeGenerator, + # which also has the effect that the following test only occurs in + # non-'single' modes. + if isinstance(node.expr, ast.Const): + return # skip LOAD_CONST/POP_TOP pairs (for e.g. docstrings) self.set_lineno(node) self.visit(node.expr) self.emit('POP_TOP') @@ -1289,7 +1311,8 @@ args, hasTupleArg = generateArgList(func.argnames) self.graph = pyassem.PyFlowGraph(name, func.filename, args, - optimized=1) + optimized=self.localsfullyknown, + newlocals=1) self.isLambda = isLambda self.super_init() @@ -1342,9 +1365,14 @@ __super_init = AbstractFunctionCode.__init__ - def __init__(self, func, scopes, isLambda, class_name, mod): + def __init__(self, func, scopes, isLambda, class_name, mod, parentscopeambiguity): self.scopes = scopes self.scope = scopes[func] + + self.localsfullyknown = self.scope.localsfullyknown + self.parentscopeambiguity = parentscopeambiguity + self.scopeambiguity = (not self.localsfullyknown or parentscopeambiguity) + self.__super_init(func, scopes, isLambda, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) @@ -1358,9 +1386,14 @@ __super_init = AbstractFunctionCode.__init__ - def __init__(self, gexp, scopes, class_name, mod): + def __init__(self, gexp, scopes, class_name, mod, parentscopeambiguity): self.scopes = scopes self.scope = scopes[gexp] + + self.localsfullyknown = self.scope.localsfullyknown + self.parentscopeambiguity = parentscopeambiguity + self.scopeambiguity = (not self.localsfullyknown or parentscopeambiguity) + self.__super_init(gexp, scopes, 1, class_name, mod) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) @@ -1394,9 +1427,13 @@ __super_init = AbstractClassCode.__init__ - def __init__(self, klass, scopes, module): + def __init__(self, klass, scopes, module, parentscopeambiguity): self.scopes = scopes self.scope = scopes[klass] + + self.parentscopeambiguity = parentscopeambiguity + self.scopeambiguity = parentscopeambiguity + self.__super_init(klass, scopes, module) self.graph.setFreeVars(self.scope.get_free_vars()) self.graph.setCellVars(self.scope.get_cell_vars()) Modified: pypy/dist/pypy/lib/_stablecompiler/symbols.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/symbols.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/symbols.py Thu Aug 25 22:18:06 2005 @@ -1,7 +1,8 @@ """Module symbol-table generator""" import ast -from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_UNKNOWN +from consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, \ + SC_UNKNOWN, SC_DEFAULT from misc import mangle import types @@ -11,6 +12,7 @@ MANGLE_LEN = 256 class Scope: + localsfullyknown = True # XXX how much information do I need about each name? def __init__(self, name, module, klass=None): self.name = name @@ -20,6 +22,7 @@ self.globals = {} self.params = {} self.frees = {} + self.hasbeenfree = {} self.cells = {} self.children = [] # nested is true if the class could contain free variables, @@ -100,7 +103,7 @@ if self.nested: return SC_UNKNOWN else: - return SC_GLOBAL + return SC_DEFAULT def get_free_vars(self): if not self.nested: @@ -111,6 +114,7 @@ if not (self.defs.has_key(name) or self.globals.has_key(name)): free[name] = 1 + self.hasbeenfree.update(free) return free.keys() def handle_children(self): @@ -133,7 +137,8 @@ Be careful to stop if a child does not think the name is free. """ - self.globals[name] = 1 + if name not in self.defs: + self.globals[name] = 1 if self.frees.has_key(name): del self.frees[name] for child in self.children: @@ -237,6 +242,12 @@ self.visit(node.code, scope) self.handle_free_vars(scope, parent) + def visitExec(self, node, parent): + if not (node.globals or node.locals): + parent.localsfullyknown = False # bare exec statement + for child in node.getChildNodes(): + self.visit(child, parent) + def visitGenExpr(self, node, parent): scope = GenExprScope(self.module, self.klass); if parent.nested or isinstance(parent, FunctionScope) \ @@ -331,6 +342,7 @@ def visitFrom(self, node, scope): for name, asname in node.names: if name == "*": + scope.localsfullyknown = False continue scope.add_def(asname or name) Modified: pypy/dist/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/transformer.py Thu Aug 25 22:18:06 2005 @@ -172,24 +172,26 @@ raise WalkerError, ('unexpected node type', n) def single_input(self, node): - ### do we want to do anything about being "interactive" ? # NEWLINE | simple_stmt | compound_stmt NEWLINE n = node[0][0] if n != token.NEWLINE: - return self.com_stmt(node[0]) - - return Pass() + stmt = self.com_stmt(node[0]) + else: + stmt = Pass() + return Module(None, stmt) def file_input(self, nodelist): doc = self.get_docstring(nodelist, symbol.file_input) - if doc is not None: - i = 1 - else: - i = 0 stmts = [] - for node in nodelist[i:]: + for node in nodelist: if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: self.com_append_stmt(stmts, node) + + if doc is not None: + assert isinstance(stmts[0], Discard) + assert isinstance(stmts[0].expr, Const) + del stmts[0] + return Module(doc, Stmt(stmts)) def eval_input(self, nodelist): @@ -255,7 +257,8 @@ if args[0] == symbol.varargslist: names, defaults, flags = self.com_arglist(args[1:]) else: - names = defaults = () + names = [] + defaults = [] flags = 0 doc = self.get_docstring(nodelist[-1]) @@ -704,7 +707,7 @@ def atom_lsqb(self, nodelist): if nodelist[1][0] == token.RSQB: - return List(()) + return List([]) return self.com_list_constructor(nodelist[1]) def atom_lbrace(self, nodelist): @@ -929,6 +932,7 @@ l = self.com_node(node) if l.__class__ in (Name, Slice, Subscript, Getattr): return l + print node # XXX raise SyntaxError, "can't assign to %s" % l.__class__.__name__ def com_assign(self, node, assigning): From rxe at codespeak.net Thu Aug 25 22:42:53 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 25 Aug 2005 22:42:53 +0200 (CEST) Subject: [pypy-svn] r16559 - pypy/dist/pypy/translator/llvm2/module Message-ID: <20050825204253.6058427B54@code1.codespeak.net> Author: rxe Date: Thu Aug 25 22:42:52 2005 New Revision: 16559 Removed: pypy/dist/pypy/translator/llvm2/module/ll_os.py pypy/dist/pypy/translator/llvm2/module/ll_os_path.py Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/support.py Log: Add the remaining functions to generate (ll_os). (ericvrp/rxe) Modified: pypy/dist/pypy/translator/llvm2/module/extfunction.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/extfunction.py (original) +++ pypy/dist/pypy/translator/llvm2/module/extfunction.py Thu Aug 25 22:42:52 2005 @@ -38,9 +38,9 @@ extfunctions = {} #dependencies, llvm-code -import support, ll_os +import support -for module in (support, ll_os): +for module in (support,): extdeclarations += module.extdeclarations extfunctions.update(module.extfunctions) extdeclarations += '\n;application function prototypes' Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Thu Aug 25 22:42:52 2005 @@ -3,8 +3,6 @@ #include #include -#define NULL (void *) 0 - #define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW // c forward declarations @@ -13,10 +11,12 @@ struct RPyFREXP_RESULT; struct RPyMODF_RESULT; struct RPyString; +struct RPySTAT_RESULT; struct RPyFREXP_RESULT *ll_frexp_result__Float_Signed(double, int); struct RPyMODF_RESULT *ll_modf_result__Float_Float(double, double); - +struct RPySTAT_RESULT *ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(int, int, int, int, int, + int, int, int, int, int); char *RPyString_AsString(struct RPyString*); int RPyString_Size(struct RPyString*); struct RPyString *RPyString_FromString(char *); @@ -24,6 +24,9 @@ void prepare_and_raise_OverflowError(char *); void prepare_and_raise_ValueError(char *); void prepare_and_raise_IOError(char *); +void ll_raise_OSError__Signed(int error); + +#define RPYTHON_RAISE_OSERROR(error) ll_raise_OSError__Signed(error) int ll_math_is_error(double x) { if (errno == ERANGE) { @@ -490,3 +493,195 @@ return RPyString_FromString(buffer); } +/************************************************************/ + /*** C header subsection: os module ***/ + +#if !(defined(MS_WIN64) || defined(MS_WINDOWS)) +# include +# include +# include +#endif + +#include +#include +#ifndef PATH_MAX + /* assume windows */ +# define PATH_MAX 254 +#endif + +/* The functions below are mapped to functions from pypy.rpython.module.* + by the pypy.translator.c.extfunc.EXTERNALS dictionary. + They should correspond to the functions with the suggested_primitive + flag set, and NOT necessarily directly to the ll_os_*() functions. + See for example ll_read_into(), which is called by ll_os_read(). + The latter would be messy to write here, but ll_read_into() is quite easy. +*/ + + +/* just do what CPython is doing... */ + +#if defined(MS_WIN64) || defined(MS_WINDOWS) +# define STAT _stati64 +# define FSTAT _fstati64 +# define STRUCT_STAT struct _stati64 +#else +# define STAT stat +# define FSTAT fstat +# define STRUCT_STAT struct stat +#endif + + +int ll_os_open(struct RPyString *filename, int flag, int mode) +{ + /* XXX unicode_file_names */ + char buf[PATH_MAX]; + int fd, namelen = RPyString_Size(filename); + if (namelen >= PATH_MAX) { + RPYTHON_RAISE_OSERROR(ENAMETOOLONG); + return -1; + } + else { + memcpy(buf, RPyString_AsString(filename), namelen); + buf[namelen] = 0; + fd = open(buf, flag, mode); + if (fd < 0) + RPYTHON_RAISE_OSERROR(errno); + return fd; + } +} + +long ll_read_into(int fd, struct RPyString *buffer) +{ + long n = read(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); + if (n < 0) + RPYTHON_RAISE_OSERROR(errno); + return n; +} + +long ll_os_write(int fd, struct RPyString *buffer) +{ + long n = write(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); + if (n < 0) + RPYTHON_RAISE_OSERROR(errno); + return n; +} + +void ll_os_close(int fd) +{ + if (close(fd) < 0) + RPYTHON_RAISE_OSERROR(errno); +} + +int ll_os_dup(int fd) +{ + fd = dup(fd); + if (fd < 0) + RPYTHON_RAISE_OSERROR(errno); + return fd; +} + +struct RPyString *ll_os_getcwd(void) +{ + char buf[PATH_MAX]; + char *res; + res = getcwd(buf, sizeof buf); + if (res == NULL) { + RPYTHON_RAISE_OSERROR(errno); + return NULL; + } + return RPyString_FromString(buf); +} + +struct RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) { + long res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; + res0 = (long)st.st_mode; + res1 = (long)st.st_ino; /*XXX HAVE_LARGEFILE_SUPPORT!*/ + res2 = (long)st.st_dev; /*XXX HAVE_LONG_LONG!*/ + res3 = (long)st.st_nlink; + res4 = (long)st.st_uid; + res5 = (long)st.st_gid; + res6 = (long)st.st_size; /*XXX HAVE_LARGEFILE_SUPPORT!*/ + res7 = (long)st.st_atime; /*XXX ignoring quite a lot of things for time here */ + res8 = (long)st.st_mtime; /*XXX ignoring quite a lot of things for time here */ + res9 = (long)st.st_ctime; /*XXX ignoring quite a lot of things for time here */ + /*XXX ignoring BLOCK info here*/ + + return ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(res0, res1, res2, res3, res4, + res5, res6, res7, res8, res9); +} + + +struct RPySTAT_RESULT* ll_os_stat(struct RPyString * fname) { + STRUCT_STAT st; + int error = STAT(RPyString_AsString(fname), &st); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + return NULL; + } + return _stat_construct_result_helper(st); +} + +struct RPySTAT_RESULT* ll_os_fstat(long fd) { + STRUCT_STAT st; + int error = FSTAT(fd, &st); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + return NULL; + } + return _stat_construct_result_helper(st); +} + +long ll_os_lseek(long fd, long pos, long how) { +#if defined(MS_WIN64) || defined(MS_WINDOWS) + PY_LONG_LONG res; +#else + off_t res; +#endif +#ifdef SEEK_SET + /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ + switch (how) { + case 0: how = SEEK_SET; break; + case 1: how = SEEK_CUR; break; + case 2: how = SEEK_END; break; + } +#endif /* SEEK_END */ +#if defined(MS_WIN64) || defined(MS_WINDOWS) + res = _lseeki64(fd, pos, how); +#else + res = lseek(fd, pos, how); +#endif + if (res < 0) + RPYTHON_RAISE_OSERROR(errno); + return res; +} + +long ll_os_isatty(long fd) { + return (int)isatty((int)fd); +} + +#ifdef HAVE_FTRUNCATE +void ll_os_ftruncate(long fd, long length) { /*XXX add longfile support */ + int res; + res = ftruncate((int)fd, (off_t)length); + if (res < 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} +#endif + +struct RPyString *ll_os_strerror(int errnum) { + char *res; + res = strerror(errnum); + return RPyString_FromString(res); +} + +long ll_os_system(struct RPyString * fname) { + return system(RPyString_AsString(fname)); +} + +void ll_os_unlink(struct RPyString * fname) { + int error = unlink(RPyString_AsString(fname)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Thu Aug 25 22:42:52 2005 @@ -6,7 +6,7 @@ declare ccc uint %strlen(sbyte*) declare ccc int %strcmp(sbyte*, sbyte*) declare ccc sbyte* %memset(sbyte*, int, uint) - +declare ccc sbyte* %strncpy(sbyte *, sbyte *, int) %__print_debug_info = internal global bool false %__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" """ From hpk at codespeak.net Fri Aug 26 10:25:34 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 10:25:34 +0200 (CEST) Subject: [pypy-svn] r16564 - pypy/dist/pypy/doc Message-ID: <20050826082534.88CE227B45@code1.codespeak.net> Author: hpk Date: Fri Aug 26 10:25:32 2005 New Revision: 16564 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/index.txt pypy/dist/pypy/doc/interpreter.txt Log: - improved/refined bytecode interpreter documentation - fixed index.txt to not link to _sre_pypy which is gone Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Fri Aug 26 10:25:32 2005 @@ -1,7 +1,8 @@ .. _`demo/`: ../../demo .. _`lib-python/`: ../../lib-python -.. _`annotation/`: -.. _`pypy/annotation`: ../../pypy/annotation +.. _`lib-python/2.4.1/dis.py`: ../../lib-python/2.4.1/dis.py +.. _`pypy/annotation`: +.. _`annotation/`: ../../pypy/annotation .. _`annotation/binaryop.py`: ../../pypy/annotation/binaryop.py .. _`doc/`: ../../pypy/doc .. _`doc/revreport/`: ../../pypy/doc/revreport @@ -15,23 +16,23 @@ .. _`pypy/interpreter/nestedscope.py`: ../../pypy/interpreter/nestedscope.py .. _`pypy/interpreter/pyopcode.py`: ../../pypy/interpreter/pyopcode.py .. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py -.. _`lib/`: -.. _`pypy/lib/`: ../../pypy/lib -.. _`lib/test2/`: -.. _`pypy/lib/test2`: ../../pypy/lib/test2 -.. _`module/`: -.. _`pypy/module`: ../../pypy/module +.. _`pypy/lib/`: +.. _`lib/`: ../../pypy/lib +.. _`pypy/lib/test2`: +.. _`lib/test2/`: ../../pypy/lib/test2 +.. _`pypy/module`: +.. _`module/`: ../../pypy/module .. _`module/__builtin__/`: ../../pypy/module/__builtin__ .. _`pypy/module/__builtin__/__init__.py`: ../../pypy/module/__builtin__/__init__.py -.. _`module/_sre_pypy/`: ../../pypy/module/_sre_pypy +.. _`module/_sre/`: ../../pypy/module/_sre .. _`module/parser/`: ../../pypy/module/parser .. _`module/recparser/`: ../../pypy/module/recparser .. _`module/sys/`: ../../pypy/module/sys .. _`objspace/`: .. _`pypy/objspace`: ../../pypy/objspace .. _`objspace/flow/`: ../../pypy/objspace/flow -.. _`objspace/std/`: -.. _`pypy/objspace/std`: ../../pypy/objspace/std +.. _`pypy/objspace/std`: +.. _`objspace/std/`: ../../pypy/objspace/std .. _`objspace/thunk.py`: ../../pypy/objspace/thunk.py .. _`objspace/trace.py`: .. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py @@ -44,8 +45,8 @@ .. _`tool/`: ../../pypy/tool .. _`tool/pytest/`: ../../pypy/tool/pytest .. _`tool/tb_server/`: ../../pypy/tool/tb_server -.. _`translator/`: -.. _`pypy/translator`: ../../pypy/translator +.. _`pypy/translator`: +.. _`translator/`: ../../pypy/translator .. _`pypy/translator/annrpython.py`: ../../pypy/translator/annrpython.py .. _`translator/c/`: ../../pypy/translator/c .. _`translator/java/`: ../../pypy/translator/java Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Aug 26 10:25:32 2005 @@ -34,6 +34,7 @@ `license`_ contains licensing details (basically a straight MIT-license). +.. _FAQ: faq.html .. _parser: parser.html .. _`talks and related projects`: extradoc.html .. _`license`: http://codespeak.net/svn/pypy/dist/LICENSE @@ -73,8 +74,7 @@ `module/`_ contains `mixed modules`_ implementing core modules with both application and interpreter level code -`module/_sre_pypy/`_ an experimental approach wrapping CPython's ``_sre`` module - without using faking +`module/_sre/`_ full regular expression implementation `module/__builtin__/`_ full implementation of CPython's ``__builtin__`` module. Modified: pypy/dist/pypy/doc/interpreter.txt ============================================================================== --- pypy/dist/pypy/doc/interpreter.txt (original) +++ pypy/dist/pypy/doc/interpreter.txt Fri Aug 26 10:25:32 2005 @@ -15,25 +15,38 @@ `Bytecode Interpreter`_ and related Virtual Machine functionalities. PyPy's bytecode interpreter has a structure reminiscent of -CPython's Virtual Machine: Source code is parsed and compiled -into code objects which encapsulate information about their -respective functions, class and module body source codes. -Interpreting such code objects means instantiating and -initializing a `Frame class`_ and then calling its -``frame.eval()`` method. This entry point then interprets -each bytecode. +CPython's Virtual Machine: It processes code objects parsed +and compiled from Python source code. Code objects contain +contensed information about their respective functions, class and +module body source codes. Interpreting such code objects means +instantiating and initializing a `Frame class`_ and then +calling its ``frame.eval()`` method. This main entry point +initialise appropriate namespaces and then interprets each +bytecode instruction. Python's standard library contains +the `lib-python/2.4.1/dis.py`_ module which allows to view +the Virtual's machine bytecode instructions:: + + >>> import dis + >>> def f(x): + return x + 1 + >>> dis.dis(f) + 4 0 LOAD_FAST 0 (x) + 3 LOAD_CONST 1 (1) + 6 BINARY_ADD + 7 RETURN_VALUE CPython as well as PyPy are stack-based virtual machines, i.e. they don't have registers but put object to and pull objects from a stack. The bytecode interpreter is only responsible for implementing control flow and putting and pulling black -box objects to and from the value stack. It does not know how -to perform operations on those black box (`wrapped`_) objects -for which it delegates to the `object space`_. In order to -implement a branch in a program's execution, however, it needs -to gain minimal knowledge about a wrapped object. Thus, each -object space has to offer a ``is_true(w_obj)`` operation which -returns an interpreter-level boolean value. +box objects to and from this value stack. The bytecode interpreter +does not know how to perform operations on those black box +(`wrapped`_) objects for which it delegates to the `object +space`_. In order to implement a conditional branch in a program's +execution, however, it needs to gain minimal knowledge about a +wrapped object. Thus, each object space has to offer a +``is_true(w_obj)`` operation which returns an +interpreter-level boolean value. For the understanding of the interpreter's inner workings it is crucial to recognize the concepts of `interpreter-level and @@ -55,25 +68,26 @@ transparent invocation of application-level helpers (``app2interp``) at interpreter-level. -Another task of the bytecode interpreter is to expose its basic -code, frame, module and function objects to application-level +Another task of the bytecode interpreter is to care for exposing its +basic code, frame, module and function objects to application-level code. Such runtime introspection and modification abilities are implemented via `interpreter descriptors`_ (also see Raymond Hettingers `how-to guide for descriptors`_ in Python, PyPy uses this model extensively). -A significant complexity lies in `argument parsing`_. Python as a -language offers very flexible ways of providing and receiving arguments +A significant complexity lies in `function argument parsing`_. Python as a +language offers flexible ways of providing and receiving arguments for a particular function invocation. Not only does it take special care to get this right, it also presents difficulties for the `annotation pass`_ which performs a whole-program analysis on the bytecode interpreter, argument parsing and gatewaying code -in order to infer the types of all flowing values. +in order to infer the types of all values flowing across function +calls. It is for this reason that PyPy resorts to generate specialized frame classes and functions at `initialization -time`_ in order to let the annotator only see static program -flows with homogenous name-value assignments on e.g. function -invocations. +time`_ in order to let the annotator only see rather static +program flows with homogenous name-value assignments on +function invocations. .. _`how-to guide for descriptors`: http://users.rcn.com/python/download/Descriptor.htm .. _`annotation pass`: translation.html#the-annotation-pass @@ -85,8 +99,7 @@ Bytecode Interpreter Implementation Classes -=========================================== - +================================================ .. _`Frame class`: .. _`Frame`: @@ -94,8 +107,8 @@ Frame classes ----------------- -The concept of Frames is pervasive in executing programs and -virtual machines in particular. They are sometimes called +The concept of Frames is pervasive in executing programs and +on virtual machines in particular. They are sometimes called *execution frame* because they hold crucial information regarding the execution of a Code_ object, which in turn is often directly related to a Python `Function`_. Frame @@ -104,7 +117,7 @@ - the local scope holding name-value bindings, usually implemented via a "fast scope" which is an array of wrapped objects -- a blockstack which has (nested) information regarding the +- a blockstack containing (nested) information regarding the control flow of a function (such as ``while`` and ``try`` constructs) - a value stack where bytecode interpretation pulls object @@ -190,7 +203,7 @@ the function given an `Arguments`_ class instance. .. _Arguments: -.. _`argument parsing`: +.. _`function argument parsing`: Arguments Class -------------------- @@ -232,12 +245,14 @@ * ``__file__`` the source filename from which this module was instantiated * ``__path__`` state used for relative imports -Apart from the basic Module used for importing application-level files -there is a more refined ``MixedModule`` class (see `pypy/interpreter/mixedmodule.py`_) -which allows to define name-value bindings both at application level -and at interpreter level. See the ``__builtin__`` module's -`pypy/module/__builtin__/__init__.py`_ file for an example -and the higher level `chapter on Modules in the coding guide`_. +Apart from the basic Module used for importing +application-level files there is a more refined +``MixedModule`` class (see `pypy/interpreter/mixedmodule.py`_) +which allows to define name-value bindings both at application +level and at interpreter level. See the ``__builtin__`` +module's `pypy/module/__builtin__/__init__.py`_ file for an +example and the higher level `chapter on Modules in the coding +guide`_. .. _`__builtin__ module`: http://codespeak.net/svn/pypy/dist/pypy/module/ .. _`chapter on Modules in the coding guide`: coding-guide.html#modules @@ -248,12 +263,13 @@ ---------------------- A unique PyPy property is the ability to easily cross the barrier -between interpreted code and machine-level code. Both codes are -implemented via Python source code but they usually look differently. +between interpreted and machine-level code (often refered to as +the difference between `interpreter-level and application-level`_). Be aware that the according code (in `pypy/interpreter/gateway.py`_) -for crossing the barrier in both directions is somewhat involved, mostly -due to the fact that the type-infering annotator needs to keep -track of the types of objects flowing across those barriers. +for crossing the barrier in both directions is somewhat +involved, mostly due to the fact that the type-infering +annotator needs to keep track of the types of objects flowing +across those barriers. Making interpreter-level functions available at application-level +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ From hpk at codespeak.net Fri Aug 26 10:26:18 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 10:26:18 +0200 (CEST) Subject: [pypy-svn] r16565 - pypy/dist/pypy/module/sys Message-ID: <20050826082618.9D0FC27B45@code1.codespeak.net> Author: hpk Date: Fri Aug 26 10:26:16 2005 New Revision: 16565 Modified: pypy/dist/pypy/module/sys/__init__.py Log: fix the prompt for translated PyPy, finally Modified: pypy/dist/pypy/module/sys/__init__.py ============================================================================== --- pypy/dist/pypy/module/sys/__init__.py (original) +++ pypy/dist/pypy/module/sys/__init__.py Fri Aug 26 10:26:16 2005 @@ -52,8 +52,8 @@ 'version_info' : 'space.wrap((2,4,1, "alpha", 42))', 'version' : 'space.wrap("2.4.1 (pypy1 build)")', 'hexversion' : 'space.wrap(0x020401a0)', - 'ps1' : 'space.wrap(">>>>")', - 'ps2' : 'space.wrap("....")', + 'ps1' : 'space.wrap(">>>> ")', + 'ps2' : 'space.wrap(".... ")', 'displayhook' : 'hook.displayhook', '__displayhook__' : 'hook.__displayhook__', From hpk at codespeak.net Fri Aug 26 10:26:44 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 10:26:44 +0200 (CEST) Subject: [pypy-svn] r16566 - pypy/dist/pypy/tool Message-ID: <20050826082644.EABC827B45@code1.codespeak.net> Author: hpk Date: Fri Aug 26 10:26:42 2005 New Revision: 16566 Added: pypy/dist/pypy/tool/genstatistic.py (contents, props changed) Log: added a new tool that generates a web page with statistics about LOC counts for PyPy including detailed counts for sub directories Added: pypy/dist/pypy/tool/genstatistic.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/genstatistic.py Fri Aug 26 10:26:42 2005 @@ -0,0 +1,132 @@ + +import autopath +import py +from py.__.misc.cmdline import countloc + +pypydir = py.path.local(autopath.pypydir) + +def isdocfile(p): + return p.ext == '.txt' or p.basename in ('README', 'NOTES', 'LICENSE') + +def istestfile(p): + if not p.check(file=1, ext='.py'): + return False + pb = p.purebasename + if pb.startswith('test_') or pb.endswith('_test'): + return True + if 'test' in [x.basename for x in p.parts()[-4:]]: + return True + +notistestfile = lambda x: not istestfile(x) + +class relchecker: + def __init__(self, rel): + self.rel = rel + def __call__(self, p): + return p.relto(autopath.pypydir).startswith(self.rel) + +def isfile(p): + return p.check(file=1) and p.ext in ('.py', '.txt', '') + +def getpypycounter(): + def rec(p): + if p.basename[0] == '.': + return False + if p.basename in ('Pyrex', + '_cache', + 'unicodedata', + 'pypy-translation-snapshot'): + return False + return True + filecounter = countloc.FileCounter() + root = py.path.local(autopath.pypydir) + filecounter.addrecursive(root, isfile, rec=rec) + return filecounter + +class CounterModel: + def __init__(self, pypycounter): + self.counter = pypycounter + self.totallines = pypycounter.numlines + self.totalfiles = pypycounter.numfiles + self.testlines = pypycounter.getnumlines(istestfile) + self.testfiles = pypycounter.getnumfiles(istestfile) + self.notestlines = pypycounter.getnumlines(notistestfile) + self.notestfiles = pypycounter.getnumfiles(notistestfile) + self.doclines = pypycounter.getnumlines(isdocfile) + self.docfiles = pypycounter.getnumfiles(isdocfile) + +# +# rendering +# +def row(*args): + return html.tr([html.td(arg) for arg in args]) + +def percent(x, y): + return "%.2f%%" % (x / (y/100.0)) + +def viewlocsummary(model): + t = html.table( + row("total number of lines", model.totallines, " "), + row("number of testlines", model.testlines, + percent(model.testlines, model.totallines)), + row("number of non-testlines", model.notestlines, + percent(model.notestlines, model.totallines)), + + row("total number of files", model.totalfiles, " "), + row("number of testfiles", model.testfiles, + percent(model.testfiles, model.totalfiles)), + row("number of non-testfiles", model.notestfiles, + percent(model.notestfiles, model.totalfiles)), + ) + if model.docfiles: + t.append(row("number of docfiles", model.docfiles, + percent(model.docfiles, model.totalfiles))) + t.append(row("number of doclines", model.doclines, + percent(model.doclines, model.totallines))) + return t + +def viewloclist(model): + t = html.table() + d = model.counter.file2numlines + paths = d.items() + paths.sort(lambda x,y : -cmp(x[1], y[1])) # sort by numlines + for p, numlines in paths: + if numlines < 3: + continue + t.append(row(p.relto(pypydir.dirpath()), numlines)) + return t + +def viewsubdirs(model): + t = html.table() + for p in pypydir.listdir(): + if p.basename in '_cache .svn'.split(): + continue + if p.check(dir=1): + counter = countloc.FileCounter() + counter.addrecursive(p, isfile) + model = CounterModel(counter) + t.append(row(html.h2(p.relto(pypydir.dirpath())))) + t.append(viewlocsummary(model)) + t.append(viewloclist(model)) + return t + +if __name__ == '__main__': + pypycounter = getpypycounter() + model = CounterModel(pypycounter) + rev = py.path.svnwc(autopath.pypydir).info().rev + html = py.xml.html + doc = html.html( + html.head( + html.title("PyPy Statistics %d" % rev), + ), + html.body( + html.h2("rev %d PyPy Summary of Files and Lines" % rev), + viewlocsummary(model), + html.h2("Details on first-level subdirectories"), + viewsubdirs(model), + html.h3("PyPy Full List Files and Lines"), + viewloclist(model), + html.p("files with less than 3 lines ignored") + ) + ) + print doc.unicode(indent=2).encode('utf8') From hpk at codespeak.net Fri Aug 26 10:33:49 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 10:33:49 +0200 (CEST) Subject: [pypy-svn] r16567 - pypy/dist/pypy/tool Message-ID: <20050826083349.3F43727B45@code1.codespeak.net> Author: hpk Date: Fri Aug 26 10:33:48 2005 New Revision: 16567 Modified: pypy/dist/pypy/tool/genstatistic.py Log: exclude certain dirs for subdir-details as well Modified: pypy/dist/pypy/tool/genstatistic.py ============================================================================== --- pypy/dist/pypy/tool/genstatistic.py (original) +++ pypy/dist/pypy/tool/genstatistic.py Fri Aug 26 10:33:48 2005 @@ -28,19 +28,20 @@ def isfile(p): return p.check(file=1) and p.ext in ('.py', '.txt', '') +def recpypy(p): + if p.basename[0] == '.': + return False + if p.basename in ('Pyrex', + '_cache', + 'unicodedata', + 'pypy-translation-snapshot'): + return False + return True + def getpypycounter(): - def rec(p): - if p.basename[0] == '.': - return False - if p.basename in ('Pyrex', - '_cache', - 'unicodedata', - 'pypy-translation-snapshot'): - return False - return True filecounter = countloc.FileCounter() root = py.path.local(autopath.pypydir) - filecounter.addrecursive(root, isfile, rec=rec) + filecounter.addrecursive(root, isfile, rec=recpypy) return filecounter class CounterModel: @@ -103,7 +104,7 @@ continue if p.check(dir=1): counter = countloc.FileCounter() - counter.addrecursive(p, isfile) + counter.addrecursive(p, isfile, recpypy) model = CounterModel(counter) t.append(row(html.h2(p.relto(pypydir.dirpath())))) t.append(viewlocsummary(model)) From hpk at codespeak.net Fri Aug 26 10:37:56 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 10:37:56 +0200 (CEST) Subject: [pypy-svn] r16568 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20050826083756.86E0127B45@code1.codespeak.net> Author: hpk Date: Fri Aug 26 10:37:56 2005 New Revision: 16568 Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py Log: rip out print statement Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Fri Aug 26 10:37:56 2005 @@ -936,7 +936,6 @@ l = self.com_node(node) if l.__class__ in (Name, Slice, Subscript, Getattr): return l - print node # XXX raise SyntaxError, "can't assign to %s" % l.__class__.__name__ def com_assign(self, node, assigning): From hpk at codespeak.net Fri Aug 26 10:40:54 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 10:40:54 +0200 (CEST) Subject: [pypy-svn] r16569 - pypy/dist/pypy/doc Message-ID: <20050826084054.71BF627B45@code1.codespeak.net> Author: hpk Date: Fri Aug 26 10:40:53 2005 New Revision: 16569 Modified: pypy/dist/pypy/doc/index.txt Log: link statistics page Modified: pypy/dist/pypy/doc/index.txt ============================================================================== --- pypy/dist/pypy/doc/index.txt (original) +++ pypy/dist/pypy/doc/index.txt Fri Aug 26 10:40:53 2005 @@ -32,6 +32,8 @@ `compliance test status`_ shows outcomes of recent compliance test runs against PyPy. +`PyPy statistics`_ shows LOC statistics about PyPy. + `license`_ contains licensing details (basically a straight MIT-license). .. _FAQ: faq.html @@ -39,6 +41,7 @@ .. _`talks and related projects`: extradoc.html .. _`license`: http://codespeak.net/svn/pypy/dist/LICENSE .. _`compliance test status`: http://codespeak.net/~hpk/pypy-testresult/ +.. _`PyPy statistics`: http://codespeak.net/~hpk/pypy-stat/ .. _`object spaces`: objspace.html .. _`translation`: translation.html .. _`coding guide`: coding-guide.html From nik at codespeak.net Fri Aug 26 10:44:05 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 10:44:05 +0200 (CEST) Subject: [pypy-svn] r16570 - pypy/dist/pypy/module/_sre Message-ID: <20050826084405.7CEED27B45@code1.codespeak.net> Author: nik Date: Fri Aug 26 10:44:01 2005 New Revision: 16570 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved op_min_repeat_one from app- to interp-level Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 26 10:44:01 2005 @@ -454,50 +454,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def op_min_repeat_one(self, ctx): - # match repeated sequence (minimizing) - # <1=min> <2=max> item tail - mincount = ctx.peek_code(2) - maxcount = ctx.peek_code(3) - #self._log(ctx, "MIN_REPEAT_ONE", mincount, maxcount) - - if ctx.remaining_chars() < mincount: - ctx.has_matched = NOT_MATCHED - yield True - ctx.state.string_position = ctx.string_position - if mincount == 0: - count = 0 - else: - count = self.count_repetitions(ctx, mincount) - if count < mincount: - ctx.has_matched = NOT_MATCHED - yield True - ctx.skip_char(count) - if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: - # tail is empty. we're finished - ctx.state.string_position = ctx.string_position - ctx.has_matched = MATCHED - yield True - - ctx.state.marks_push() - while maxcount == MAXREPEAT or count <= maxcount: - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(ctx.peek_code(1) + 1) - yield False - if child_context.has_matched == MATCHED: - ctx.has_matched = MATCHED - yield True - ctx.state.string_position = ctx.string_position - if self.count_repetitions(ctx, 1) == 0: - break - ctx.skip_char(1) - count += 1 - ctx.state.marks_pop_keep() - - ctx.state.marks_pop_discard() - ctx.has_matched = NOT_MATCHED - yield True - def op_repeat(self, ctx): # create repeat context. all the hard work is done by the UNTIL # operator (MAX_UNTIL, MIN_UNTIL) Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 10:44:01 2005 @@ -528,6 +528,64 @@ ctx.has_matched = ctx.NOT_MATCHED return True +def op_min_repeat_one(space, ctx): + # match repeated sequence (minimizing) + # <1=min> <2=max> item tail + + # Case 1: First entry point + if not ctx.is_resumed(): + mincount = ctx.peek_code(2) + maxcount = ctx.peek_code(3) + if ctx.remaining_chars() < mincount: + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.state.string_position = ctx.string_position + if mincount == 0: + count = 0 + else: + count = count_repetitions(space, ctx, mincount) + if count < mincount: + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.skip_char(count) + if ctx.peek_code(ctx.peek_code(1) + 1) == 1: # OPCODES["success"] + # tail is empty. we're finished + ctx.state.string_position = ctx.string_position + ctx.has_matched = ctx.MATCHED + return True + ctx.state.marks_push() + + # Case 2: Repetition resumed, "forwardtracking" + else: + if ctx.child_context.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + values = ctx.restore_values() + maxcount = values[0] + count = values[1] + ctx.state.string_position = ctx.string_position + if count_repetitions(space, ctx, 1) == 0: + # Tail didn't match and no more repetitions --> fail + ctx.state.marks_pop_discard() + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.skip_char(1) + count += 1 + ctx.state.marks_pop_keep() + + # Try to match tail + if maxcount == MAXREPEAT or count <= maxcount: + ctx.state.string_position = ctx.string_position + ctx.push_new_context(ctx.peek_code(1) + 1) + ctx.backup_value(maxcount) + ctx.backup_value(count) + return False + + # Failed + ctx.state.marks_pop_discard() + ctx.has_matched = ctx.NOT_MATCHED + return True + def op_jump(space, ctx): # jump forward # / @@ -630,7 +688,7 @@ None, #REPEAT, op_repeat_one, None, #SUBPATTERN, - None, #MIN_REPEAT_ONE + op_min_repeat_one, ] From ale at codespeak.net Fri Aug 26 10:44:11 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 26 Aug 2005 10:44:11 +0200 (CEST) Subject: [pypy-svn] r16571 - pypy/dist/pypy/module/_codecs/test Message-ID: <20050826084411.CE8F927B4B@code1.codespeak.net> Author: ale Date: Fri Aug 26 10:44:09 2005 New Revision: 16571 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: Added test for UnicodEncodeError, UnicodeDecodeError,UnicodeTranslateError Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Fri Aug 26 10:44:09 2005 @@ -2,6 +2,51 @@ class AppTestCodecs: + def test_unicodedecodeerror(self): + assert str(UnicodeDecodeError( + "ascii", "g\xfcrk", 1, 2, "ouch")) == "'ascii' codec can't decode byte 0xfc in position 1: ouch" + + assert str(UnicodeDecodeError( + "ascii", "g\xfcrk", 1, 3, "ouch")) == "'ascii' codec can't decode bytes in position 1-2: ouch" + + + def test_unicodetranslateerror(self): + + assert str(UnicodeTranslateError( + u"g\xfcrk", 1, 2, "ouch"))== "can't translate character u'\\xfc' in position 1: ouch" + + assert str(UnicodeTranslateError( + u"g\u0100rk", 1, 2, "ouch"))== "can't translate character u'\\u0100' in position 1: ouch" + + assert str(UnicodeTranslateError( + u"g\uffffrk", 1, 2, "ouch"))== "can't translate character u'\\uffff' in position 1: ouch" + + if sys.maxunicode > 0xffff: + assert str(UnicodeTranslateError( + u"g\U00010000rk", 1, 2, "ouch"))== "can't translate character u'\\U00010000' in position 1: ouch" + + assert str(UnicodeTranslateError( + u"g\xfcrk", 1, 3, "ouch"))=="can't translate characters in position 1-2: ouch" + + def test_unicodeencodeerror(self): + assert str(UnicodeEncodeError( + "ascii", u"g\xfcrk", 1, 2, "ouch"))=="'ascii' codec can't encode character u'\\xfc' in position 1: ouch" + + assert str(UnicodeEncodeError( + "ascii", u"g\xfcrk", 1, 4, "ouch"))== "'ascii' codec can't encode characters in position 1-3: ouch" + + assert str(UnicodeEncodeError( + "ascii", u"\xfcx", 0, 1, "ouch"))=="'ascii' codec can't encode character u'\\xfc' in position 0: ouch" + + assert str(UnicodeEncodeError( + "ascii", u"\u0100x", 0, 1, "ouch"))=="'ascii' codec can't encode character u'\\u0100' in position 0: ouch" + + assert str(UnicodeEncodeError( + "ascii", u"\uffffx", 0, 1, "ouch"))=="'ascii' codec can't encode character u'\\uffff' in position 0: ouch" + if sys.maxunicode > 0xffff: + assert str(UnicodeEncodeError( + "ascii", u"\U00010000x", 0, 1, "ouch")) =="'ascii' codec can't encode character u'\\U00010000' in position 0: ouch" + def test_indexerror(self): test = "\\" # trailing backslash @@ -21,7 +66,6 @@ ] for s in insecure: buf = "S" + s + "\012p0\012." - print s raises (ValueError, pickle.loads, buf) def test_partial_utf8(self): @@ -62,8 +106,8 @@ assert r.read() == u"" assert r.bytebuffer == "" assert r.charbuffer == u"" - encoding = 'utf-8' - check_partial(encoding, + encoding = 'utf-8' + check_partial(encoding, u"\x00\xff\u07ff\u0800\uffff", [ u"\x00", @@ -78,7 +122,7 @@ u"\x00\xff\u07ff\u0800", u"\x00\xff\u07ff\u0800\uffff", ] - ) + ) def test_partial_utf16(self): class Queue(object): From ac at codespeak.net Fri Aug 26 11:10:48 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 26 Aug 2005 11:10:48 +0200 (CEST) Subject: [pypy-svn] r16572 - in pypy/dist/pypy: lib module/_codecs/test Message-ID: <20050826091048.42D3527B45@code1.codespeak.net> Author: ac Date: Fri Aug 26 11:10:47 2005 New Revision: 16572 Modified: pypy/dist/pypy/lib/_exceptions.py pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: (arre, ale) Fix the __str__methon of UnicodeEncodeError, UnicodeDecodeError and UnicodeTranslateError to match that of CPython. Modified: pypy/dist/pypy/lib/_exceptions.py ============================================================================== --- pypy/dist/pypy/lib/_exceptions.py (original) +++ pypy/dist/pypy/lib/_exceptions.py Fri Aug 26 11:10:47 2005 @@ -147,15 +147,14 @@ raise TypeError('function takes exactly 4 arguments (%d given)'%argc) def __str__(self): - # this is a bad hack, please supply an implementation - res = ' '.join([ - 'start=' + str(getattr(self, 'start', None)), - 'reason=' + str(getattr(self, 'reason', None)), - 'args=' + str(getattr(self, 'args', None)), - 'end=' + str(getattr(self, 'end', None)), - 'object=' + str(getattr(self, 'object', None)), - ]) - return res + if self.end == self.start + 1: + badchar = ord(self.object[self.start]) + if badchar <= 0xff: + return "can't translate character u'\\x%02x' in position %d: %s" % (badchar, self.start, self.reason) + if badchar <= 0xffff: + return "can't translate character u'\\u%04x' in position %d: %s"%(badchar, self.start, self.reason) + return "can't translate character u'\\U%08x' in position %d: %s"%(badchar, self.start, self.reason) + return "can't translate characters in position %d-%d: %s" % (self.start, self.end - 1, self.reason) class LookupError(StandardError): """Base class for lookup errors.""" @@ -354,8 +353,11 @@ raise TypeError('function takes exactly 5 arguments (%d given)'%argc) def __str__(self): - return "%r codec can't decode byte %x in position %d: %s"%(self.encoding, - ord(self.object[self.start]), self.start, self.reason) + if self.end == self.start + 1: + return "%r codec can't decode byte 0x%02x in position %d: %s"%(self.encoding, + ord(self.object[self.start]), self.start, self.reason) + return "%r codec can't decode bytes in position %d-%d: %s" % ( + self.encoding, self.start, self.end - 1, self.reason) class TypeError(StandardError): """Inappropriate argument type.""" @@ -421,5 +423,16 @@ raise TypeError('function takes exactly 5 arguments (%d given)'%argc) def __str__(self): - return "%r codec can't encode character %r in position %d: %s"%(self.encoding, - self.object[self.start], self.start, self.reason) + if self.end == self.start + 1: + badchar = ord(self.object[self.start]) + if badchar <= 0xff: + return "%r codec can't encode character u'\\x%02x' in position %d: %s"%(self.encoding, + badchar, self.start, self.reason) + if badchar <= 0xffff: + return "%r codec can't encode character u'\\u%04x' in position %d: %s"%(self.encoding, + badchar, self.start, self.reason) + + return "%r codec can't encode character u'\\U%08x' in position %d: %s"%(self.encoding, + badchar, self.start, self.reason) + return "%r codec can't encode characters in position %d-%d: %s" % ( + self.encoding, self.start, self.end - 1, self.reason) Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Fri Aug 26 11:10:47 2005 @@ -11,7 +11,7 @@ def test_unicodetranslateerror(self): - + import sys assert str(UnicodeTranslateError( u"g\xfcrk", 1, 2, "ouch"))== "can't translate character u'\\xfc' in position 1: ouch" @@ -29,6 +29,7 @@ u"g\xfcrk", 1, 3, "ouch"))=="can't translate characters in position 1-2: ouch" def test_unicodeencodeerror(self): + import sys assert str(UnicodeEncodeError( "ascii", u"g\xfcrk", 1, 2, "ouch"))=="'ascii' codec can't encode character u'\\xfc' in position 1: ouch" From arigo at codespeak.net Fri Aug 26 11:31:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 11:31:08 +0200 (CEST) Subject: [pypy-svn] r16573 - pypy/dist/lib-python Message-ID: <20050826093108.0A09927B45@code1.codespeak.net> Author: arigo Date: Fri Aug 26 11:31:06 2005 New Revision: 16573 Modified: pypy/dist/lib-python/failure_list.txt Log: Updated to reflect the current state. Removed all tests that are no longer failing (or have been moved to non-core). Modified: pypy/dist/lib-python/failure_list.txt ============================================================================== --- pypy/dist/lib-python/failure_list.txt (original) +++ pypy/dist/lib-python/failure_list.txt Fri Aug 26 11:31:06 2005 @@ -1,23 +1,13 @@ -test_pprint - fails because "dict.__repr__ is dict.__repr__" equals False -test_syntax fails because "del f()" produces SyntaxError with message = - "can't assign to function call" instead of "can't delete function call". - The test is for "delete" to be in the message - -test_import - fails because os.open is case insensitive (at least on Mac os X) - -multiple tests fail because from __future__ import division does -not work (true division is never enabled) - -test_compiler - fails because of "maximum recursion depth exceeded" +test_cpickle + has been re-run, still failing -test_decorator - fails because globals and locals are None in a nested function ? +test_descr + cannot easily complete this; after another quick review, the failures + left are mostly "don't care" internal details. test_builtin + (some of these might have been fixed by now:) - our compilers need to recognize BOM markers - eval etc should accept dict subclasses - hex/oct should output '-' for negative numbers @@ -25,40 +15,34 @@ - disallow interning of string subclasses - __future__ import division problems - -test_mutants - still crashes because it does a str() on a a mutating dict - which results in a RuntimeError, what does CPython output in this case? - -test_marshal - even with our new complete marshall support enabled this one has - failures - -test_tuple etc - do we want to support x is x*1 where x is exactly a tuple? - test_extcall cannot be fixed. PyPy produces different TypeError messages but they are also correct and useful (reviewed them again). -test_tempfile - still failing +test_codecscallback + Should be fixed by now, takes a long time to re-run -test_cpickle -test_descr - have been re-run, still failing +test_compiler + not a core mode -test_multibytecodec - needs the gb18030 codec, part of the CJK codecs. either remove this test - from core or maybe fake or reimplement the CJK codecs? +test_global + should be run and pass with --compiler=pyparseapp + +test_codeop + could be fixed, maybe (being worked on) + +test_compile + test_exec_with_general_mapping_for_locals should be modified + other tests are minor stuff that seem basically fixable, mostly + missing SyntaxErrors test_traceback - test_nocaret fails because the examined SyntaxError doesn't carry a - line number +test_future +test_genexps + some SyntaxErrors don't come with a lineno attached, + but ideally we should always produce them. + A bug in test_genexps is being worked on (assignment to genexps). test_trace Fails because of our compiler generating different linenumber information than CPythons. - -test_pep292 - Depends on a working re module. From tismer at codespeak.net Fri Aug 26 11:35:23 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 11:35:23 +0200 (CEST) Subject: [pypy-svn] r16574 - in pypy/dist/pypy: rpython/module translator/c translator/c/src translator/c/test Message-ID: <20050826093523.5290E27B45@code1.codespeak.net> Author: tismer Date: Fri Aug 26 11:35:20 2005 New Revision: 16574 Modified: pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: fixed a small bug added support for chdir, mkdir, rmdir plus tests Modified: pypy/dist/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/module/ll_os.py Fri Aug 26 11:35:20 2005 @@ -112,7 +112,7 @@ def ll_os_strerror(errnum): return to_rstr(os.strerror(errnum)) -ll_os_getcwd.suggested_primitive = True +ll_os_strerror.suggested_primitive = True def ll_os_system(cmd): return os.system(from_rstr(cmd)) @@ -121,3 +121,15 @@ def ll_os_unlink(path): os.unlink(from_rstr(path)) ll_os_unlink.suggested_primitive = True + +def ll_os_chdir(path): + os.chdir(from_rstr(path)) +ll_os_chdir.suggested_primitive = True + +def ll_os_mkdir(path, mode): + os.mkdir(from_rstr(path), mode) +ll_os_chdir.suggested_primitive = True + +def ll_os_rmdir(path): + os.rmdir(from_rstr(path)) +ll_os_chdir.suggested_primitive = True Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Fri Aug 26 11:35:20 2005 @@ -15,7 +15,6 @@ ll_os .ll_os_write: 'LL_os_write', ll_os .ll_os_close: 'LL_os_close', ll_os .ll_os_dup: 'LL_os_dup', - ll_os .ll_os_getcwd: 'LL_os_getcwd', ll_os .ll_os_stat: 'LL_os_stat', ll_os .ll_os_fstat: 'LL_os_fstat', ll_os .ll_os_lseek: 'LL_os_lseek', @@ -24,6 +23,10 @@ ll_os .ll_os_strerror: 'LL_os_strerror', ll_os .ll_os_system: 'LL_os_system', ll_os .ll_os_unlink: 'LL_os_unlink', + ll_os .ll_os_getcwd: 'LL_os_getcwd', + ll_os .ll_os_chdir: 'LL_os_chdir', + ll_os .ll_os_mkdir: 'LL_os_mkdir', + ll_os .ll_os_rmdir: 'LL_os_rmdir', ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', ll_time.ll_time_time: 'LL_time_time', Modified: pypy/dist/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_os.h (original) +++ pypy/dist/pypy/translator/c/src/ll_os.h Fri Aug 26 11:35:20 2005 @@ -85,18 +85,6 @@ return fd; } -RPyString *LL_os_getcwd(void) -{ - char buf[PATH_MAX]; - char *res; - res = getcwd(buf, sizeof buf); - if (res == NULL) { - RPYTHON_RAISE_OSERROR(errno); - return NULL; - } - return RPyString_FromString(buf); -} - RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) { long res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; res0 = (long)st.st_mode; @@ -185,8 +173,41 @@ } void LL_os_unlink(RPyString * fname) { - int error = unlink(RPyString_AsString(fname)); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - } + int error = unlink(RPyString_AsString(fname)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} + +RPyString *LL_os_getcwd(void) +{ + char buf[PATH_MAX]; + char *res; + res = getcwd(buf, sizeof buf); + if (res == NULL) { + RPYTHON_RAISE_OSERROR(errno); + return NULL; + } + return RPyString_FromString(buf); +} + +void LL_os_chdir(RPyString * path) { + int error = chdir(RPyString_AsString(path)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} + +void LL_os_mkdir(RPyString * path) { + int error = mkdir(RPyString_AsString(path)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} + +void LL_os_rmdir(RPyString * path) { + int error = rmdir(RPyString_AsString(path)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } } Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/c/test/test_extfunc.py Fri Aug 26 11:35:20 2005 @@ -398,3 +398,28 @@ open(tmpfile, 'w').close() fn() assert not os.path.exists(tmpfile) + +def test_chdir(): + def does_stuff(path): + os.chdir(path) + f1 = compile(does_stuff, [str]) + curdir = os.getcwd() + try: + os.chdir('..') + except: pass # toplevel + f1(curdir) + assert curdir == os.getcwd() + +def test_mkdir_rmdir(): + def does_stuff(path, delete): + if delete: + os.rmdir(path) + else: + os.mkdir(path, 0777) + f1 = compile(does_stuff, [str, bool]) + dirname = str(udir.join('test_mkdir_rmdir')) + f1(dirname, False) + assert os.path.exists(dirname) and os.path.isdir(dirname) + f1(dirname, True) + assert not os.path.exists(dirname) + From tismer at codespeak.net Fri Aug 26 11:37:20 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 11:37:20 +0200 (CEST) Subject: [pypy-svn] r16575 - pypy/dist/pypy/objspace/std Message-ID: <20050826093720.7C00B27B45@code1.codespeak.net> Author: tismer Date: Fri Aug 26 11:37:19 2005 New Revision: 16575 Modified: pypy/dist/pypy/objspace/std/longobject.py Log: small relaxation on len(digit array). todo: make this more strict and don't uselen() at all. Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Fri Aug 26 11:37:19 2005 @@ -93,7 +93,6 @@ w_self.digits = DigitArray(digits) w_self.sign = sign w_self.space = space - assert len(w_self.digits) def fromint(space, intval): if intval < 0: @@ -138,7 +137,7 @@ def _normalize(self): if len(self.digits) == 0: self.sign = 0 - self.digits = [0] + self.digits = [] return i = len(self.digits) - 1 while i != 0 and self.digits[i] == 0: From tismer at codespeak.net Fri Aug 26 11:40:45 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 11:40:45 +0200 (CEST) Subject: [pypy-svn] r16576 - pypy/dist/pypy/translator/goal Message-ID: <20050826094045.DD39D27B45@code1.codespeak.net> Author: tismer Date: Fri Aug 26 11:40:43 2005 New Revision: 16576 Modified: pypy/dist/pypy/translator/goal/targetpypymain.py pypy/dist/pypy/translator/goal/targetpypystandalone.py pypy/dist/pypy/translator/goal/targetrichards.py pypy/dist/pypy/translator/goal/targetrpystonex.py pypy/dist/pypy/translator/goal/targetsegfault.py pypy/dist/pypy/translator/goal/translate_pypy.py Log: added a new translation option "-laptop" this saves a lot of memory, by disabling geninterplevel Modified: pypy/dist/pypy/translator/goal/targetpypymain.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypymain.py Fri Aug 26 11:40:43 2005 @@ -49,18 +49,15 @@ # _____ Define and setup target ___ -def target(): +def target(geninterp=True): global space, w_entry_point # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None - # disable geninterp for now -- we have faaar toooo much interp-level code - # for the poor translator already - # XXX why can't I enable this? crashes the annotator! space = StdObjSpace(nofaking=True, compiler="pyparseapp", translating=True, - #usemodules=['marhsal', '_sre'], - geninterp=False) + #usemodules=['marshal', '_sre'], + geninterp=geninterp) # manually imports app_main.py filename = os.path.join(this_dir, 'app_main.py') Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Fri Aug 26 11:40:43 2005 @@ -44,19 +44,15 @@ # _____ Define and setup target ___ -def target(): +def target(geninterp=True): global space, w_entry_point # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None - # disable geninterp for now -- we have faaar toooo much interp-level code - # for the poor translator already - # XXX why can't I enable this? crashes the annotator! space = StdObjSpace(nofaking=True, compiler="pyparseapp", translating=True, - #usemodules=['marhsal', '_sre'], - geninterp=True) - + #usemodules=['marshal', '_sre'], + geninterp=geninterp) # manually imports app_main.py filename = os.path.join(this_dir, 'app_main.py') w_dict = space.newdict([]) Modified: pypy/dist/pypy/translator/goal/targetrichards.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrichards.py (original) +++ pypy/dist/pypy/translator/goal/targetrichards.py Fri Aug 26 11:40:43 2005 @@ -4,7 +4,7 @@ # _____ Define and setup target ___ -def target(): +def target(*args): return entry_point, [] def get_llinterp_args(): Modified: pypy/dist/pypy/translator/goal/targetrpystonex.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrpystonex.py (original) +++ pypy/dist/pypy/translator/goal/targetrpystonex.py Fri Aug 26 11:40:43 2005 @@ -18,7 +18,7 @@ g.PtrGlbNext = None return rpystone.pystones(loops), id(g) - def target(): + def target(*args): return entry_point, [int] def run(c_entry_point): Modified: pypy/dist/pypy/translator/goal/targetsegfault.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetsegfault.py (original) +++ pypy/dist/pypy/translator/goal/targetsegfault.py Fri Aug 26 11:40:43 2005 @@ -4,7 +4,7 @@ def entry_point(i): return getitem([i, 2, 3, 4], 2) + getitem(None, i) -def target(): +def target(*args): return entry_point, [int] def get_llinterp_args(): Modified: pypy/dist/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy.py Fri Aug 26 11:40:43 2005 @@ -38,6 +38,12 @@ be either .py or .zip . -llinterpret interprets the flow graph after rtyping it + -laptop try to save as much memory as possible, since laptops tend to + have less than a gigabyte of memory (512 MB is typical). + Currently, we avoid to use geninterplevel, which creates a lot + of extra blocks, but gains only som 10-20 % of speed, because + we are still lacking annotation of applevel code. + -batch don't use interactive helpers,like pdb """ import autopath, sys, os @@ -101,7 +107,7 @@ policy = AnnotatorPolicy() if target: - spec = target() + spec = target(not options['-laptop']) try: entry_point, inputtypes, policy = spec except ValueError: @@ -352,6 +358,7 @@ '-fork': False, '-fork2': False, '-llinterpret': False, + '-laptop': False, '-batch': False, } listen_port = None From tismer at codespeak.net Fri Aug 26 11:44:12 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 11:44:12 +0200 (CEST) Subject: [pypy-svn] r16577 - pypy/dist/pypy/interpreter Message-ID: <20050826094412.4177627B45@code1.codespeak.net> Author: tismer Date: Fri Aug 26 11:44:11 2005 New Revision: 16577 Modified: pypy/dist/pypy/interpreter/pyopcode.py Log: added debug output for missing opcode. I stepped into this when using compiled code from 2.5 by chance, and was hit by opcode "LIST_APPEND" Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Fri Aug 26 11:44:11 2005 @@ -693,16 +693,24 @@ def EXTENDED_ARG(f, oparg): opcode = f.nextop() oparg = oparg<<16 | f.nextarg() - fn = f.dispatch_table_w_arg[opcode] + fn = f.dispatch_table_w_arg[opcode] if fn is None: - raise pyframe.BytecodeCorruption + raise pyframe.BytecodeCorruption fn(f, oparg) def MISSING_OPCODE(f): - raise pyframe.BytecodeCorruption, "unknown opcode" + ofs = f.next_instr - 1 + c = f.pycode.co_code[ofs] + name = f.pycode.co_name + raise pyframe.BytecodeCorruption("unknown opcode, ofs=%d, code=%d, name=%s" % + (ofs, ord(c), name) ) def MISSING_OPCODE_W_ARG(f, oparg): - raise pyframe.BytecodeCorruption, "unknown opcode" + ofs = f.next_instr - 3 + c = f.pycode.co_code[ofs] + name = f.pycode.co_name + raise pyframe.BytecodeCorruption("unknown opcode, ofs=%d, code=%d, name=%s" % + (ofs, ord(c), name) ) ### dispatch_table ### @@ -745,7 +753,7 @@ ### helpers written at the application-level ### # Some of these functions are expected to be generally useful if other -# parts of the code needs to do the same thing as a non-trivial opcode, +# parts of the code need to do the same thing as a non-trivial opcode, # like finding out which metaclass a new class should have. # This is why they are not methods of PyInterpFrame. # There are also a couple of helpers that are methods, defined in the From tismer at codespeak.net Fri Aug 26 11:45:13 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 11:45:13 +0200 (CEST) Subject: [pypy-svn] r16578 - in pypy/dist/pypy: module/posix rpython Message-ID: <20050826094513.23A8327B45@code1.codespeak.net> Author: tismer Date: Fri Aug 26 11:45:11 2005 New Revision: 16578 Modified: pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/module/posix/interp_posix.py pypy/dist/pypy/rpython/extfunctable.py Log: added some basic extensions to the posix module Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Fri Aug 26 11:45:11 2005 @@ -27,22 +27,16 @@ 'system' : 'interp_posix.system', 'unlink' : 'interp_posix.unlink', 'remove' : 'interp_posix.remove', + 'getcwd' : 'interp_posix.getcwd', + 'chdir' : 'interp_posix.chdir', + 'mkdir' : 'interp_posix.mkdir', + 'rmdir' : 'interp_posix.rmdir', } if hasattr(os, 'ftruncate'): interpleveldefs['ftruncate'] = 'interp_posix.ftruncate' -for constant in ['EX_CANTCREAT', 'EX_CONFIG', 'EX_DATAERR', 'EX_IOERR', - 'EX_NOHOST', 'EX_NOINPUT', 'EX_NOPERM', 'EX_NOUSER', - 'EX_OK', 'EX_OSERR', 'EX_OSFILE', 'EX_PROTOCOL', - 'EX_SOFTWARE', 'EX_TEMPFAIL', 'EX_UNAVAILABLE', 'EX_USAGE', - 'F_OK', 'NGROUPS_MAX', 'O_APPEND', 'O_CREAT', 'O_DIRECT', - 'O_DIRECTORY', 'O_DSYNC', 'O_EXCL', 'O_LARGEFILE', 'O_NDELAY', - 'O_NOCTTY', 'O_NOFOLLOW', 'O_NONBLOCK', 'O_RDONLY', 'O_RDWR', - 'O_RSYNC', 'O_SYNC', 'O_TRUNC', 'O_WRONLY', 'R_OK', 'TMP_MAX', - 'WCONTINUED', 'WNOHANG', 'WUNTRACED', 'W_OK', 'X_OK']: - try: - Module.interpleveldefs[constant] = ("space.wrap(%s)" % - (getattr(os, constant), )) - except AttributeError: - pass +for constant in dir(os): + value = getattr(os, constant) + if constant.isupper() and type(value) is int: + Module.interpleveldefs[constant] = "space.wrap(%s)" % value Modified: pypy/dist/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/dist/pypy/module/posix/interp_posix.py (original) +++ pypy/dist/pypy/module/posix/interp_posix.py Fri Aug 26 11:45:11 2005 @@ -99,15 +99,6 @@ return build_stat_result(space, st) stat.unwrap_spec = [ObjSpace, str] -def getcwd(space): - try: - cur = os.getcwd() - except OSError, e: - raise wrap_oserror(space, e) - else: - return space.wrap(cur) -getcwd.unwrap_spec = [ObjSpace] - def dup(space, fd): try: newfd = os.dup(fd) @@ -148,3 +139,42 @@ except OSError, e: raise wrap_oserror(space, e) remove.unwrap_spec = [ObjSpace, str] + +def getcwd(space): + try: + cur = os.getcwd() + except OSError, e: + raise wrap_oserror(space, e) + else: + return space.wrap(cur) +getcwd.unwrap_spec = [ObjSpace] + +def chdir(space, path): + """chdir(path) + +Change the current working directory to the specified path.""" + try: + os.chdir(path) + except OSError, e: + raise wrap_oserror(space, e) +chdir.unwrap_spec = [ObjSpace, str] + +def mkdir(space, path, mode=0777): + """mkdir(path [, mode=0777]) + +Create a directory.""" + try: + os.mkdir(path, mode) + except OSError, e: + raise wrap_oserror(space, e) +mkdir.unwrap_spec = [ObjSpace, str, int] + +def rmdir(space, path): + """rmdir(path) + +Remove a directory.""" + try: + os.rmdir(path) + except OSError, e: + raise wrap_oserror(space, e) +rmdir.unwrap_spec = [ObjSpace, str] Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Fri Aug 26 11:45:11 2005 @@ -133,7 +133,6 @@ declare(os.read , str , 'll_os/read') declare(os.write , posannotation , 'll_os/write') declare(os.close , noneannotation, 'll_os/close') -declare(os.getcwd , str , 'll_os/getcwd') declare(os.dup , int , 'll_os/dup') declare(os.lseek , int , 'll_os/lseek') declare(os.isatty , bool , 'll_os/isatty') @@ -142,8 +141,12 @@ declare(os.fstat , statannotation, 'll_os/fstat') declare(os.stat , statannotation, 'll_os/stat') declare(os.system , int , 'll_os/system') -declare(os.unlink , noneannotation, 'll_os/unlink') declare(os.strerror , str , 'll_os/strerror') +declare(os.unlink , noneannotation, 'll_os/unlink') +declare(os.getcwd , str , 'll_os/getcwd') +declare(os.chdir , noneannotation, 'll_os/chdir') +declare(os.mkdir , noneannotation, 'll_os/mkdir') +declare(os.rmdir , noneannotation, 'll_os/rmdir') declare(os.path.exists, bool , 'll_os_path/exists') declare(os.path.isdir, bool , 'll_os_path/isdir') declare(time.time , float , 'll_time/time') From tismer at codespeak.net Fri Aug 26 11:54:34 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 11:54:34 +0200 (CEST) Subject: [pypy-svn] r16580 - in pypy/dist/pypy: fakecompiler interpreter lib/_stablecompiler Message-ID: <20050826095434.BD45127B45@code1.codespeak.net> Author: tismer Date: Fri Aug 26 11:54:33 2005 New Revision: 16580 Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py pypy/dist/pypy/fakecompiler/readme.txt pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/lib/_stablecompiler/apphook.py Log: worked hard on making the compiled pypy do testing. This had the side effect of many fixes, so it was not lost. But there are still problems. First thing: when I use the half-faked compiler to compile test_complex, pypy crashes with a core dump. For that reason, I also added a mode to fake the complete compiler. That finally works, but then _sre is missing. We need to decide if we want to continue with this right now. Modified: pypy/dist/pypy/fakecompiler/fakecompiler.py ============================================================================== --- pypy/dist/pypy/fakecompiler/fakecompiler.py (original) +++ pypy/dist/pypy/fakecompiler/fakecompiler.py Fri Aug 26 11:54:33 2005 @@ -1,13 +1,27 @@ -import parser, marshal, os +import parser, marshal, os, __future__ DUMPFILE = 'this_is_the_marshal_file' -def reallycompile(tuples, filename, mode, flag_names): - # XXX : use the flags if possible - return parser.compileast(parser.tuple2ast(tuples), filename) +def reallycompile(tuples_or_src, filename, mode, flag_names): + if type(tuples_or_src) is str: + flags = 0 + if 'nested_scopes' in flag_names: + flags |= __future__.CO_NESTED + if 'generators' in flag_names: + flags |= __future__.CO_GENERATOR_ALLOWED + if 'division' in flag_names: + flags |= __future__.CO_FUTURE_DIVISION + return compile(tuples_or_src, filename, mode, flags) + return parser.compileast(parser.tuple2ast(tuples_or_src), filename) if __name__ == '__main__': - tuples, filename, mode, done, flag_names = marshal.load(file(DUMPFILE, "rb")) - code = reallycompile(tuples, filename, mode, flag_names) + s = file(DUMPFILE, "rb").read() + tup = marshal.loads(s) + tuples_or_src, filename, mode, done, flag_names = tup + try: + code = reallycompile(tuples_or_src, filename, mode, flag_names) + except SyntaxError, e: + code = e.msg, (e.filename, e.lineno, e.offset, e.text) done = True - marshal.dump( (code, filename, mode, done ), file(DUMPFILE, "wb"), 1) + tup = (code, filename, mode, done, flag_names) + marshal.dump( tup, file(DUMPFILE, "wb")) Modified: pypy/dist/pypy/fakecompiler/readme.txt ============================================================================== --- pypy/dist/pypy/fakecompiler/readme.txt (original) +++ pypy/dist/pypy/fakecompiler/readme.txt Fri Aug 26 11:54:33 2005 @@ -14,3 +14,15 @@ - there must be a file named "pythonname" which contains the complete filename of a Python 1.4.2 compatible binary. Please, add this by hand for your installation. + +Latest addtion: + +The current compiler seems to be instable. For instance, it +crashes completely without a message on test_complex. +Therefore, I added a new option: + +- If the folder with fakecompiler.py also contains a file + named "fakecompletely", the whole compilation process + is redirected to a real CPython process. + +I very much hope that this crap can be removed, ASAP (chris) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Fri Aug 26 11:54:33 2005 @@ -5,7 +5,7 @@ from codeop import PyCF_DONT_IMPLY_DEDENT from pypy.interpreter.error import OperationError from pypy.rpython.objectmodel import we_are_translated - +import os class AbstractCompiler: """Abstract base class for a bytecode compiler.""" @@ -117,10 +117,10 @@ space.wrap(e.offset), space.wrap(e.text)])]) raise OperationError(space.w_SyntaxError, w_synerr) - except ValueError,e: - raise OperationError(space.w_ValueError,space.wrap(str(e))) - except TypeError,e: - raise OperationError(space.w_TypeError,space.wrap(str(e))) + except ValueError, e: + raise OperationError(space.w_ValueError, space.wrap(str(e))) + except TypeError, e: + raise OperationError(space.w_TypeError, space.wrap(str(e))) from pypy.interpreter.pycode import PyCode return PyCode(space)._from_code(c) compile._annspecialcase_ = "override:cpy_compile" @@ -182,7 +182,7 @@ XXX: This class should override the baseclass implementation of compile_command() in order to optimize it, especially in case - of incomplete inputs (e.g. we shouldn't re-compile from sracth + of incomplete inputs (e.g. we shouldn't re-compile from scratch the whole source after having only added a new '\n') """ def compile(self, source, filename, mode, flags): @@ -231,23 +231,24 @@ space.wrap(e.offset), space.wrap(e.text)])]) raise OperationError(space.w_SyntaxError, w_synerr) - except UnicodeDecodeError, e: + except UnicodeDecodeError, e: raise OperationError(space.w_UnicodeDecodeError, space.newtuple([ space.wrap(e.encoding), space.wrap(e.object), space.wrap(e.start), space.wrap(e.end), space.wrap(e.reason)])) - except ValueError,e: + except ValueError, e: if e.__class__ != ValueError: extra_msg = "(Really go %s)" % e.__class__.__name__ else: extra_msg = "" - raise OperationError(space.w_ValueError,space.wrap(str(e)+extra_msg)) - except TypeError,e: - raise OperationError(space.w_TypeError,space.wrap(str(e))) + raise OperationError(space.w_ValueError, space.wrap(str(e)+extra_msg)) + except TypeError, e: + raise OperationError(space.w_TypeError, space.wrap(str(e))) # __________ end of XXX above from pypy.interpreter.pycode import PyCode return PyCode(space)._from_code(c) compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' + class PythonCompilerApp(PythonCompiler): """Temporary. Calls the stablecompiler package at app-level.""" @@ -259,7 +260,21 @@ self._load_compilers() debug_print(" done") + def compile(self, source, filename, mode, flags): + if (os.path.exists('fakecompletely') and + os.path.exists('fakecompiler.py')): + self.printmessage("faking all of compiler, cause" + " fakecompletely and fakecompiler.py" + " are in curdir") + return self.fakecompile(source, filename, mode, flags) + return PythonCompiler.compile(self, source, filename, mode, flags) + def _load_compilers(self): + # note: all these helpers, including the + # remote compiler, must be initialized early, + # or we get annotation errors. An alternative + # would be to use applevel instances, instead. + # But this code should anyway go away, soon. self.w_compileapp = self.space.appexec([], r'''(): from _stablecompiler import apphook return apphook.applevelcompile @@ -279,7 +294,6 @@ space.call_function(self.w_printmessage, space.wrap(msg)) def _get_compiler(self, mode): - from pypy.interpreter.error import debug_print import os if os.path.exists('fakecompiler.py') and mode != 'single': self.printmessage("faking compiler, because fakecompiler.py" @@ -320,6 +334,40 @@ space.wrap("code object expected")) return code + def fakecompile(self, source, filename, mode, flags): + flags |= __future__.generators.compiler_flag # always on (2.2 compat) + flag_names = get_flag_names(flags) + space = self.space + + w_flag_names = space.newlist( [ space.wrap(n) for n in flag_names ] ) + try: + w_code = space.call_function(self.w_compilefake, + space.wrap(source), + space.wrap(filename), + space.wrap(mode), + w_flag_names) + except OperationError, err: + if not err.match(space, space.w_SyntaxError): + raise + # unfortunately, we need to unnormalize the wrapped SyntaxError, + # or the w_value comparison will not work. + w_inst = err.w_value + w = space.wrap + w_synerr = space.newtuple( + [space.getattr(w_inst, w('msg')), + space.newtuple([space.getattr(w_inst, w('filename')), + space.getattr(w_inst, w('lineno')), + space.getattr(w_inst, w('offset')), + space.getattr(w_inst, w('text'))])]) + raise OperationError(space.w_SyntaxError, w_synerr) + + code = space.interpclass_w(w_code) + from pypy.interpreter.pycode import PyCode + if not isinstance(code, PyCode): + raise OperationError(space.w_RuntimeError, + space.wrap("code object expected")) + return code + class PythonAstCompiler(CPythonCompiler): """Uses the stdlib's python implementation of compiler @@ -384,6 +432,58 @@ #compile_parse_result._annspecialcase_ = 'override:cpy_stablecompiler' +class CPythonRemoteCompiler(AbstractCompiler): + """Faked implementation of a compiler, using an external Python's compile().""" + + def __init__(self, space): + AbstractCompiler.__init__(self, space) + self.w_compilefake = self.space.appexec([], r'''(): + from _stablecompiler import apphook + return apphook.fakeapplevelcompile + ''') + + def compile(self, source, filename, mode, flags): + flags |= __future__.generators.compiler_flag # always on (2.2 compat) + flag_names = get_flag_names(flags) + space = self.space + return None + + w_code = space.call_function(self.w_compilefake, + space.wrap(source), + space.wrap(filename), + space.wrap(mode), + space.wrap(flag_names)) + code = space.interpclass_w(w_code) + return code + + try: + w_code = space.call_function(self.w_compilefake, + space.wrap(source), + space.wrap(filename), + space.wrap(mode), + space.wrap(flag_names)) + except OperationError, err: + if not err.match(space, space.w_SyntaxError): + raise + # unfortunately, we need to unnormalize the wrapped SyntaxError, + # or the w_value comparison will not work. + w_inst = err.w_value + w = space.wrap + w_synerr = space.newtuple( + [space.getattr(w_inst, w('msg')), + space.newtuple([space.getattr(w_inst, w('filename')), + space.getattr(w_inst, w('lineno')), + space.getattr(w_inst, w('offset')), + space.getattr(w_inst, w('text'))])]) + raise OperationError(space.w_SyntaxError, w_synerr) + + code = space.interpclass_w(w_code) + from pypy.interpreter.pycode import PyCode + if not isinstance(code, PyCode): + raise OperationError(space.w_RuntimeError, + space.wrap("code object expected")) + return code + class PyPyCompiler(CPythonCompiler): """Uses the PyPy implementation of Compiler Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Fri Aug 26 11:54:33 2005 @@ -26,10 +26,10 @@ DUMPFILE = 'this_is_the_marshal_file' -def fakeapplevelcompile(tuples, filename, mode, flag_names): +def fakeapplevelcompile(tuples_or_src, filename, mode, flag_names): import os, marshal done = False - data = marshal.dumps( (tuples, filename, mode, done, flag_names) ) + data = marshal.dumps( (tuples_or_src, filename, mode, done, flag_names)) f = file(DUMPFILE, "wb") f.write(data) f.close() @@ -37,10 +37,12 @@ f = file(DUMPFILE, "rb") data = f.read() f.close() - code, filename, mode, done = marshal.loads(data) + code_or_syntax, filename, mode, done, flag_names = marshal.loads(data) if not done: raise ValueError, "could not fake compile!" - return code + if type(code_or_syntax) is tuple: + raise SyntaxError(*code_or_syntax) + return code_or_syntax def get_python(): try: From hpk at codespeak.net Fri Aug 26 11:56:29 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 11:56:29 +0200 (CEST) Subject: [pypy-svn] r16581 - pypy/extradoc/sprintinfo Message-ID: <20050826095629.E01AF27B45@code1.codespeak.net> Author: hpk Date: Fri Aug 26 11:56:29 2005 New Revision: 16581 Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt Log: update after session from today Modified: pypy/extradoc/sprintinfo/heidelberg-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/heidelberg-planning.txt (original) +++ pypy/extradoc/sprintinfo/heidelberg-planning.txt Fri Aug 26 11:56:29 2005 @@ -1,20 +1,20 @@ PyPy Heidelberg sprint planning (22th-29st August) ----------------------------------------------------- -Armin Rigo -Samuele Pedroni -Carl Friedrich Bolz -Niklaus Haldimann -Holger Krekel -Richard Emslie -Jacob Hallen -Laura Creighton -Ludovic Aubry -Anders Chrigstroem -Christian Tismer -Anders Lehmann -Beatrice Duering -Eric van Riet Paap +Armin Rigo rel +Samuele Pedroni rel +Carl Friedrich Bolz rel/GC +Niklaus Haldimann [work on _sre] +Holger Krekel rel +Richard Emslie llvm/rel +Eric van Riet Paap [llvm/rel] +Jacob Hallen [manage] +Laura Creighton [rel] +Ludovic Aubry [rel] +Anders Chrigstroem [rel] +Christian Tismer [rel] +Anders Lehmann [rel] +Beatrice Duering [rel/sprint-driven dev] Rough Week planning:: each day: 10 AM - 7 PM (lunch break at ~1-3pm) @@ -32,28 +32,39 @@ Release (PyPy-0.7):: - - Documentation work: - - update getting_started.txt to reflect the 0.7 release - and include instruction on how to translate - - possibly streamline the tool chain (for genc/llvm) - - do we have an easy-to-explain tool chain working for win32? - fix download locations, prepare/try out packaging - - RELEASE CUTTING friday morning: + - RELEASE CUTTING - copy pypy/dist to pypy/release/0.7.x and work on 0.7.x regarding remaining release issues + + documentation/all release-issues from the tracker + are worked on in the release-branch, including documentation + - which documentation should be served on the web page? Probably just serving dist would fit for now. + - NOTE: the translated pypy versions should be named: + + pypy-c [--info --version] richards.py + pypy-c-boehm + pypy-llvm + + the version should be 0.7.0 + + - to be done: entry-point commandline option parsing/repr-of-info + Translation - Finish GIL-based threading: backend support, fix bugs? - - mostly done (missing: rtyper support for dict with int keys) + + seems to work: but still needs checks if it translates and + then runs successfully (possibly lurking segfaults). - Isolate refcounting in genc, and have an option to enable and use Boehm instead - isolating done, there is a test for Boehm, but not implemented + DONE: you can use boehm with a translation of PyPy + interpreting richards.py. (translate_pypy.py -boehm) 2.4.1 Compliance:: @@ -66,14 +77,21 @@ eval(unicode) which means that compile(unicode) does not work currently. (see issue in the tracker, ludovic will try to look into this briefly) + - Fix/adjust/prioritize compliance test problems done: fixed binascii problems. - - (tismer) in-progress: speeding up compilation on the + + - (tismer) mostly done: speeding up compilation on the translated pypy version by doing an external cpython-invocation to produce the code object. + one can use an external python invocation to compile + from an AST to code objects to speed up compilation + for the translated PyPy. pypy/fakecompiler should be moved + to pypy/lib/_fakecompiler + - Some other "non-core" tests revealing real bugs/problems? - - from wednesday morning on most of us should work + - DONE SO FAR: from wednesday morning on most of us should work on compliancy related issues (mostly everybody) - (holger) try to fix the problem that you have to be in @@ -93,6 +111,7 @@ - compiling unicode strings (see failing test_builtins) https://codespeak.net/issue/pypy-dev/issue97 + - interactive mode parsing (issue115 -- use "single" instead of "exec"? look at code.py from lib-python/2.4.1/) high priority: why is "from __future__" not working? (flag missing?) @@ -106,12 +125,11 @@ - Do we still miss important os.* functionality? - FIXED: errno (easy for now) - Enable our own array/_sre when translating - (try with the current _sre and its interp-level parts, - otherwise just use the app-level - one) (nik) in progress (trying to get '_sre' to translate) - ^^^ getting there - - (Review builtin modules again to see if we missed something) - - 'math' must be finished (math.log()) + applevel _sre should be put into pypy/lib/ + (mixed re-module is well in progress towards becoming + translateable) + - mostly done: 'math' must be finished (math.log()) + left: enable by default. Fix/garden issues for the release in the tracker:: @@ -121,8 +139,15 @@ LLVM backend (richard, eric):: - - Improvement work to stabilize and match genc - - (Try to share code with genc?) + - done (see next point) Improvement work to stabilize and match genc + + - somewhat done: Try to share code with genc (c-code resused by) + + - status: external function implementations are reused from gen-c + by using the llvm-c-frontend. The latter is installed on codespeak + and can be run remotely from a client. (the underlying problem + is that the llvm-c frontend is hard to install). + GC (carl friedrich, samuele):: From ludal at codespeak.net Fri Aug 26 11:57:14 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 11:57:14 +0200 (CEST) Subject: [pypy-svn] r16582 - in pypy/dist/pypy: interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050826095714.0AD2F27B45@code1.codespeak.net> Author: ludal Date: Fri Aug 26 11:57:11 2005 New Revision: 16582 Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/lib/_stablecompiler/transformer.py Log: - report error when assigning to genexp Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Fri Aug 26 11:57:11 2005 @@ -984,6 +984,9 @@ def com_assign_tuple(self, node, assigning): assigns = [] + if len(node)>=3: + if node[2][0] == symbol.gen_for: + raise SyntaxError("assign to generator expression not possible") for i in range(1, len(node), 2): assigns.append(self.com_assign(node[i], assigning)) return AssTuple(assigns, lineno=extractLineNo(node)) Modified: pypy/dist/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/transformer.py Fri Aug 26 11:57:11 2005 @@ -981,6 +981,9 @@ def com_assign_tuple(self, node, assigning): assigns = [] + if len(node)>=3: + if node[2][0] == symbol.gen_for: + raise SyntaxError("assign to generator expression not possible") for i in range(1, len(node), 2): assigns.append(self.com_assign(node[i], assigning)) return AssTuple(assigns, lineno=extractLineNo(node)) From arigo at codespeak.net Fri Aug 26 11:58:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 11:58:18 +0200 (CEST) Subject: [pypy-svn] r16583 - pypy/dist/pypy/rpython/module Message-ID: <20050826095818.CCE0227B45@code1.codespeak.net> Author: arigo Date: Fri Aug 26 11:58:17 2005 New Revision: 16583 Modified: pypy/dist/pypy/rpython/module/ll_os.py Log: Typos Modified: pypy/dist/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_os.py (original) +++ pypy/dist/pypy/rpython/module/ll_os.py Fri Aug 26 11:58:17 2005 @@ -128,8 +128,8 @@ def ll_os_mkdir(path, mode): os.mkdir(from_rstr(path), mode) -ll_os_chdir.suggested_primitive = True +ll_os_mkdir.suggested_primitive = True def ll_os_rmdir(path): os.rmdir(from_rstr(path)) -ll_os_chdir.suggested_primitive = True +ll_os_rmdir.suggested_primitive = True From tismer at codespeak.net Fri Aug 26 11:58:56 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 11:58:56 +0200 (CEST) Subject: [pypy-svn] r16584 - in pypy/dist/pypy: fakecompiler lib/_fakecompiler Message-ID: <20050826095856.072B527B45@code1.codespeak.net> Author: tismer Date: Fri Aug 26 11:58:54 2005 New Revision: 16584 Added: pypy/dist/pypy/lib/_fakecompiler/ - copied from r16580, pypy/dist/pypy/fakecompiler/ Removed: pypy/dist/pypy/fakecompiler/ Log: moved fakecompiler into lib/_fakecompiler From arigo at codespeak.net Fri Aug 26 12:13:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 12:13:46 +0200 (CEST) Subject: [pypy-svn] r16587 - in pypy/dist/pypy/interpreter: pyparser test Message-ID: <20050826101346.8CF2827B45@code1.codespeak.net> Author: arigo Date: Fri Aug 26 12:13:45 2005 New Revision: 16587 Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py pypy/dist/pypy/interpreter/test/test_compiler.py Log: Fixed (?) the interactive prompt. Apparently, the hackish fixes we tried to make it work with the (wrong) mode 'exec' are not needed in the correct mode 'single': adding a NEWLINE token at the end of *any* input seems to do the trick. Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Fri Aug 26 12:13:45 2005 @@ -101,6 +101,9 @@ and the line on which the token was found. The line passed is the logical line; continuation lines are included. """ + #for line in lines: + # print repr(line) + #print '------------------- flags=%s ---->' % flags token_list = [] lnum = parenlev = continued = 0 namechars = NAMECHARS @@ -295,11 +298,14 @@ for indent in indents[1:]: # pop remaining indent levels tok = Token(pytoken.DEDENT, '') token_list.append((tok, line, lnum, pos)) - if token_list and token_list[-1][0].codename != pytoken.NEWLINE: - token_list.append((Token(pytoken.NEWLINE, ''), '\n', lnum, 0)) + #if token_list and token_list[-1][0].codename != pytoken.NEWLINE: + token_list.append((Token(pytoken.NEWLINE, ''), '\n', lnum, 0)) tok = Token(pytoken.ENDMARKER, '',) token_list.append((tok, line, lnum, pos)) + #for t in token_list: + # print '%20s %-25s %d' % (pytoken.tok_name.get(t[0].codename, '?'), t[0], t[-2]) + #print '----------------------------------------- pyparser/pythonlexer.py' return token_list, encoding class PythonSource(TokenSource): Modified: pypy/dist/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_compiler.py (original) +++ pypy/dist/pypy/interpreter/test/test_compiler.py Fri Aug 26 12:13:45 2005 @@ -23,25 +23,26 @@ unicode('\xc3\xa5', 'utf8')) def test_compile_command(self): - c0 = self.compiler.compile_command('\t # hello\n ', '?', 'exec', 0) - c1 = self.compiler.compile_command('print 6*7', '?', 'exec', 0) - c2 = self.compiler.compile_command('if 1:\n x\n', '?', 'exec', 0) - assert c0 is not None - assert c1 is not None - assert c2 is not None - c3 = self.compiler.compile_command('if 1:\n x', '?', 'exec', 0) - c4 = self.compiler.compile_command('x = (', '?', 'exec', 0) - c5 = self.compiler.compile_command('x = (\n', '?', 'exec', 0) - c6 = self.compiler.compile_command('x = (\n\n', '?', 'exec', 0) - c7 = self.compiler.compile_command('x = """a\n', '?', 'exec', 0) - assert c3 is None - assert c4 is None - assert c5 is None - assert c6 is None - assert c7 is None - space = self.space - space.raises_w(space.w_SyntaxError, self.compiler.compile_command, - 'if 1:\n x x', '?', 'exec', 0) + for mode in ('single', 'exec'): + c0 = self.compiler.compile_command('\t # hello\n ', '?', mode, 0) + c1 = self.compiler.compile_command('print 6*7', '?', mode, 0) + c2 = self.compiler.compile_command('if 1:\n x\n', '?', mode, 0) + assert c0 is not None + assert c1 is not None + assert c2 is not None + c3 = self.compiler.compile_command('if 1:\n x', '?', mode, 0) + c4 = self.compiler.compile_command('x = (', '?', mode, 0) + c5 = self.compiler.compile_command('x = (\n', '?', mode, 0) + c6 = self.compiler.compile_command('x = (\n\n', '?', mode, 0) + c7 = self.compiler.compile_command('x = """a\n', '?', mode, 0) + assert c3 is None + assert c4 is None + assert c5 is None + assert c6 is None + assert c7 is None + space = self.space + space.raises_w(space.w_SyntaxError, self.compiler.compile_command, + 'if 1:\n x x', '?', mode, 0) def test_getcodeflags(self): code = self.compiler.compile('from __future__ import division\n', From rxe at codespeak.net Fri Aug 26 12:43:03 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 26 Aug 2005 12:43:03 +0200 (CEST) Subject: [pypy-svn] r16590 - pypy/dist/pypy/translator/c/src Message-ID: <20050826104303.05B9627B45@code1.codespeak.net> Author: rxe Date: Fri Aug 26 12:43:02 2005 New Revision: 16590 Modified: pypy/dist/pypy/translator/c/src/ll_strtod.h Log: (ericvrp/rxe) Small fix to when we call free(). Modified: pypy/dist/pypy/translator/c/src/ll_strtod.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_strtod.h (original) +++ pypy/dist/pypy/translator/c/src/ll_strtod.h Fri Aug 26 12:43:02 2005 @@ -45,10 +45,10 @@ last = s + (buf_size-1); x = strtod(s, &fail_pos); errno = 0; - free(s); if (fail_pos > last) fail_pos = last; if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { + free(s); RPyRaiseSimpleException(PyExc_ValueError, "invalid float literal"); return -1.0; } @@ -56,6 +56,7 @@ x = strtod(s, NULL); errno = 0; } + free(s); return x; } From ale at codespeak.net Fri Aug 26 12:43:09 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 26 Aug 2005 12:43:09 +0200 (CEST) Subject: [pypy-svn] r16591 - pypy/dist/pypy/lib Message-ID: <20050826104309.8A0E427B49@code1.codespeak.net> Author: ale Date: Fri Aug 26 12:43:08 2005 New Revision: 16591 Modified: pypy/dist/pypy/lib/cPickle.py Log: Added handling of keyword arguments Modified: pypy/dist/pypy/lib/cPickle.py ============================================================================== --- pypy/dist/pypy/lib/cPickle.py (original) +++ pypy/dist/pypy/lib/cPickle.py Fri Aug 26 12:43:08 2005 @@ -16,13 +16,13 @@ PythonPickler = Pickler class Pickler(PythonPickler): - def __init__(self, *args): + def __init__(self, *args, **kw): self.__f = None if len(args) == 1 and isinstance(args[0], int): self.__f = StringIO() - PythonPickler.__init__(self, self.__f, args[0]) + PythonPickler.__init__(self, self.__f, args[0], **kw) else: - PythonPickler.__init__(self, *args) + PythonPickler.__init__(self, *args, **kw) def memoize(self, obj): self.memo[None] = None # cPickle starts counting at one From arigo at codespeak.net Fri Aug 26 12:45:28 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 12:45:28 +0200 (CEST) Subject: [pypy-svn] r16592 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050826104528.8F34727B45@code1.codespeak.net> Author: arigo Date: Fri Aug 26 12:45:27 2005 New Revision: 16592 Added: pypy/dist/lib-python/modified-2.4.1/test/test_codeop.py - copied, changed from r16587, pypy/dist/lib-python/2.4.1/test/test_codeop.py Log: Disabled some tests from test_codeop.py, which don't make extremely much sense anyway (see comment in file). This fails because our lexer is not lazy enough. From cfbolz at codespeak.net Fri Aug 26 12:46:19 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 12:46:19 +0200 (CEST) Subject: [pypy-svn] r16593 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20050826104619.34AF727B45@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 12:46:18 2005 New Revision: 16593 Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Log: Use the same name for all code objects of lambda functions, as in CPython, instead of using a counter. Modified: pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/pycodegen.py Fri Aug 26 12:46:18 2005 @@ -1296,15 +1296,13 @@ class AbstractFunctionCode: optimized = 1 - lambdaCount = 0 def __init__(self, func, scopes, isLambda, class_name, mod): self.class_name = class_name self.module = mod if isLambda: klass = FunctionCodeGenerator - name = "" % klass.lambdaCount - klass.lambdaCount = klass.lambdaCount + 1 + name = "" else: name = func.name From cfbolz at codespeak.net Fri Aug 26 12:48:44 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 12:48:44 +0200 (CEST) Subject: [pypy-svn] r16595 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050826104844.270BF27B45@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 12:48:43 2005 New Revision: 16595 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py Log: Fix the test for pythonlexer. Modified: pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py Fri Aug 26 12:48:43 2005 @@ -49,9 +49,8 @@ s = """['a' ]""" tokens = parse_source(s) - assert tokens == [Token(LSQB, None), Token(STRING, "'a'"), - Token(RSQB, None), Token(NEWLINE, ''), - Token(ENDMARKER, '')] + assert tokens[:4] == [Token(LSQB, None), Token(STRING, "'a'"), + Token(RSQB, None), Token(NEWLINE, '')] def test_numbers(): """make sure all kind of numbers are correctly parsed""" @@ -66,9 +65,8 @@ def test_hex_number(): """basic pasrse""" tokens = parse_source("a = 0x12L") - assert tokens == [Token(NAME, 'a'), Token(EQUAL, None), - Token(NUMBER, '0x12L'), Token(NEWLINE, ''), - Token(ENDMARKER, '')] + assert tokens[:4] == [Token(NAME, 'a'), Token(EQUAL, None), + Token(NUMBER, '0x12L'), Token(NEWLINE, '')] def test_punct(): """make sure each punctuation is correctly parsed""" From arigo at codespeak.net Fri Aug 26 12:51:10 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 12:51:10 +0200 (CEST) Subject: [pypy-svn] r16596 - in pypy/dist/pypy/module/errno: . test Message-ID: <20050826105110.64FCD27B45@code1.codespeak.net> Author: arigo Date: Fri Aug 26 12:51:04 2005 New Revision: 16596 Modified: pypy/dist/pypy/module/errno/ (props changed) pypy/dist/pypy/module/errno/__init__.py (props changed) pypy/dist/pypy/module/errno/interp_errno.py (props changed) pypy/dist/pypy/module/errno/test/ (props changed) pypy/dist/pypy/module/errno/test/test_errno.py (props changed) Log: fixeol From arigo at codespeak.net Fri Aug 26 12:54:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 12:54:29 +0200 (CEST) Subject: [pypy-svn] r16597 - pypy/dist/pypy/lib/_stablecompiler Message-ID: <20050826105429.6314C27B45@code1.codespeak.net> Author: arigo Date: Fri Aug 26 12:54:29 2005 New Revision: 16597 Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py pypy/dist/pypy/lib/_stablecompiler/transformer.py Log: More compiler merging: svn merge -r 16555:16596 http://codespeak.net/svn/pypy/dist/pypy/interpreter/stablecompiler Modified: pypy/dist/pypy/lib/_stablecompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/pycodegen.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/pycodegen.py Fri Aug 26 12:54:29 2005 @@ -1297,15 +1297,13 @@ class AbstractFunctionCode: optimized = 1 - lambdaCount = 0 def __init__(self, func, scopes, isLambda, class_name, mod): self.class_name = class_name self.module = mod if isLambda: klass = FunctionCodeGenerator - name = "" % klass.lambdaCount - klass.lambdaCount = klass.lambdaCount + 1 + name = "" else: name = func.name Modified: pypy/dist/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/transformer.py Fri Aug 26 12:54:29 2005 @@ -932,7 +932,6 @@ l = self.com_node(node) if l.__class__ in (Name, Slice, Subscript, Getattr): return l - print node # XXX raise SyntaxError, "can't assign to %s" % l.__class__.__name__ def com_assign(self, node, assigning): From cfbolz at codespeak.net Fri Aug 26 13:07:00 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 13:07:00 +0200 (CEST) Subject: [pypy-svn] r16598 - pypy/dist/lib-python/modified-2.4.1 Message-ID: <20050826110700.BF5F627B45@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 13:07:00 2005 New Revision: 16598 Added: pypy/dist/lib-python/modified-2.4.1/linecache.py - copied, changed from r16593, pypy/dist/lib-python/2.4.1/linecache.py Log: For now, use Richard's idea to optimize linecache.py until we figure out why readlines() is so slow in 'U'-mode files. From nik at codespeak.net Fri Aug 26 13:10:26 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 13:10:26 +0200 (CEST) Subject: [pypy-svn] r16599 - pypy/dist/pypy/lib Message-ID: <20050826111026.5BE9F27B47@code1.codespeak.net> Author: nik Date: Fri Aug 26 13:10:25 2005 New Revision: 16599 Added: pypy/dist/pypy/lib/_sre.py (contents, props changed) Log: added pure app-levle _sre (circular import issue resolved). this is used by default. with --usemodules=_sre the significatnly faster but not yet translateable MixedModule is used. Added: pypy/dist/pypy/lib/_sre.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/lib/_sre.py Fri Aug 26 13:10:25 2005 @@ -0,0 +1,1287 @@ +# NOT_RPYTHON +""" +A pure Python reimplementation of the _sre module from CPython 2.4 +Copyright 2005 Nik Haldimann, licensed under the MIT license + +This code is based on material licensed under CNRI's Python 1.6 license and +copyrighted by: Copyright (c) 1997-2001 by Secret Labs AB +""" +# Identifying as _sre from Python 2.3 or 2.4 +import sys +if sys.version_info[:2] >= (2, 4): + MAGIC = 20031017 +else: + MAGIC = 20030419 + +import array, operator +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 + + +# In _sre.c this is bytesize of the code word type of the C implementation. +# There it's 2 for normal Python builds and more for wide unicode builds (large +# enough to hold a 32-bit UCS-4 encoded character). Since here in pure Python +# we only see re bytecodes as Python longs, we shouldn't have to care about the +# codesize. But sre_compile will compile some stuff differently depending on the +# codesize (e.g., charsets). +if sys.maxunicode == 65535: + CODESIZE = 2 +else: + CODESIZE = 4 + +copyright = "_sre.py 2.4b Copyright 2005 by Nik Haldimann" + + +def getcodesize(): + return CODESIZE + + +def compile(pattern, flags, code, groups=0, groupindex={}, indexgroup=[None]): + """Compiles (or rather just converts) a pattern descriptor to a SRE_Pattern + object. Actual compilation to opcodes happens in sre_compile.""" + return SRE_Pattern(pattern, flags, code, groups, groupindex, indexgroup) + +def getlower(char_ord, flags): + if (char_ord < 128) or (flags & SRE_FLAG_UNICODE) \ + or (flags & SRE_FLAG_LOCALE and char_ord < 256): + return ord(unichr(char_ord).lower()) + else: + return char_ord + + +class SRE_Pattern(object): + + def __init__(self, pattern, flags, code, groups=0, groupindex={}, indexgroup=[None]): + self.pattern = pattern + self.flags = flags + self.groups = groups + self.groupindex = groupindex # Maps group names to group indices + self._indexgroup = indexgroup # Maps indices to group names + self._code = code + + def match(self, string, pos=0, endpos=sys.maxint): + """If zero or more characters at the beginning of string match this + regular expression, return a corresponding MatchObject instance. Return + None if the string does not match the pattern.""" + state = _State(string, pos, endpos, self.flags) + if state.match(self._code): + return SRE_Match(self, state) + else: + return None + + def search(self, string, pos=0, endpos=sys.maxint): + """Scan through string looking for a location where this regular + expression produces a match, and return a corresponding MatchObject + instance. Return None if no position in the string matches the + pattern.""" + state = _State(string, pos, endpos, self.flags) + if state.search(self._code): + return SRE_Match(self, state) + else: + return None + + def findall(self, string, pos=0, endpos=sys.maxint): + """Return a list of all non-overlapping matches of pattern in string.""" + matchlist = [] + state = _State(string, pos, endpos, self.flags) + while state.start <= state.end: + state.reset() + state.string_position = state.start + if not state.search(self._code): + break + match = SRE_Match(self, state) + if self.groups == 0 or self.groups == 1: + item = match.group(self.groups) + else: + item = match.groups("") + matchlist.append(item) + if state.string_position == state.start: + state.start += 1 + else: + state.start = state.string_position + return matchlist + + def _subx(self, template, string, count=0, subn=False): + filter = template + if not callable(template) and "\\" in template: + # handle non-literal strings ; hand it over to the template compiler + import sre + filter = sre._subx(self, template) + state = _State(string, 0, sys.maxint, self.flags) + sublist = [] + + n = last_pos = 0 + while not count or n < count: + state.reset() + state.string_position = state.start + if not state.search(self._code): + break + if last_pos < state.start: + sublist.append(string[last_pos:state.start]) + if not (last_pos == state.start and + last_pos == state.string_position and n > 0): + # the above ignores empty matches on latest position + if callable(filter): + sublist.append(filter(SRE_Match(self, state))) + else: + sublist.append(filter) + last_pos = state.string_position + n += 1 + if state.string_position == state.start: + state.start += 1 + else: + state.start = state.string_position + + if last_pos < state.end: + sublist.append(string[last_pos:state.end]) + item = "".join(sublist) + if subn: + return item, n + else: + return item + + def sub(self, repl, string, count=0): + """Return the string obtained by replacing the leftmost non-overlapping + occurrences of pattern in string by the replacement repl.""" + return self._subx(repl, string, count, False) + + def subn(self, repl, string, count=0): + """Return the tuple (new_string, number_of_subs_made) found by replacing + the leftmost non-overlapping occurrences of pattern with the replacement + repl.""" + return self._subx(repl, string, count, True) + + def split(self, string, maxsplit=0): + """Split string by the occurrences of pattern.""" + splitlist = [] + state = _State(string, 0, sys.maxint, self.flags) + n = 0 + last = state.start + while not maxsplit or n < maxsplit: + state.reset() + state.string_position = state.start + if not state.search(self._code): + break + if state.start == state.string_position: # zero-width match + if last == state.end: # or end of string + break + state.start += 1 + continue + splitlist.append(string[last:state.start]) + # add groups (if any) + if self.groups: + match = SRE_Match(self, state) + splitlist.extend(list(match.groups(None))) + n += 1 + last = state.start = state.string_position + splitlist.append(string[last:state.end]) + return splitlist + + def finditer(self, string, pos=0, endpos=sys.maxint): + """Return a list of all non-overlapping matches of pattern in string.""" + scanner = self.scanner(string, pos, endpos) + return iter(scanner.search, None) + + def scanner(self, string, start=0, end=sys.maxint): + return SRE_Scanner(self, string, start, end) + + def __copy__(self): + raise TypeError, "cannot copy this pattern object" + + def __deepcopy__(self): + raise TypeError, "cannot copy this pattern object" + + +class SRE_Scanner(object): + """Undocumented scanner interface of sre.""" + + def __init__(self, pattern, string, start, end): + self.pattern = pattern + self._state = _State(string, start, end, self.pattern.flags) + + def _match_search(self, matcher): + state = self._state + state.reset() + state.string_position = state.start + match = None + if matcher(self.pattern._code): + match = SRE_Match(self.pattern, state) + if match is None or state.string_position == state.start: + state.start += 1 + else: + state.start = state.string_position + return match + + def match(self): + return self._match_search(self._state.match) + + def search(self): + return self._match_search(self._state.search) + + +class SRE_Match(object): + + def __init__(self, pattern, state): + self.re = pattern + self.string = state.string + self.pos = state.pos + self.endpos = state.end + self.lastindex = state.lastindex + if self.lastindex < 0: + self.lastindex = None + self.regs = self._create_regs(state) + if pattern._indexgroup and 0 <= self.lastindex < len(pattern._indexgroup): + # The above upper-bound check should not be necessary, as the re + # compiler is supposed to always provide an _indexgroup list long + # enough. But the re.Scanner class seems to screw up something + # there, test_scanner in test_re won't work without upper-bound + # checking. XXX investigate this and report bug to CPython. + self.lastgroup = pattern._indexgroup[self.lastindex] + else: + self.lastgroup = None + + def _create_regs(self, state): + """Creates a tuple of index pairs representing matched groups.""" + regs = [(state.start, state.string_position)] + for group in range(self.re.groups): + mark_index = 2 * group + if mark_index + 1 < len(state.marks) \ + and state.marks[mark_index] is not None \ + and state.marks[mark_index + 1] is not None: + regs.append((state.marks[mark_index], state.marks[mark_index + 1])) + else: + regs.append((-1, -1)) + return tuple(regs) + + def _get_index(self, group): + if isinstance(group, int): + if group >= 0 and group <= self.re.groups: + return group + else: + if self.re.groupindex.has_key(group): + return self.re.groupindex[group] + raise IndexError("no such group") + + def _get_slice(self, group, default): + group_indices = self.regs[group] + if group_indices[0] >= 0: + return self.string[group_indices[0]:group_indices[1]] + else: + return default + + def start(self, group=0): + """Returns the indices of the start of the substring matched by group; + group defaults to zero (meaning the whole matched substring). Returns -1 + if group exists but did not contribute to the match.""" + return self.regs[self._get_index(group)][0] + + def end(self, group=0): + """Returns the indices of the end of the substring matched by group; + group defaults to zero (meaning the whole matched substring). Returns -1 + if group exists but did not contribute to the match.""" + return self.regs[self._get_index(group)][1] + + def span(self, group=0): + """Returns the 2-tuple (m.start(group), m.end(group)).""" + return self.start(group), self.end(group) + + def expand(self, template): + """Return the string obtained by doing backslash substitution and + resolving group references on template.""" + import sre + return sre._expand(self.re, self, template) + + def groups(self, default=None): + """Returns a tuple containing all the subgroups of the match. The + default argument is used for groups that did not participate in the + match (defaults to None).""" + groups = [] + for indices in self.regs[1:]: + if indices[0] >= 0: + groups.append(self.string[indices[0]:indices[1]]) + else: + groups.append(default) + return tuple(groups) + + def groupdict(self, default=None): + """Return a dictionary containing all the named subgroups of the match. + The default argument is used for groups that did not participate in the + match (defaults to None).""" + groupdict = {} + for key, value in self.re.groupindex.items(): + groupdict[key] = self._get_slice(value, default) + return groupdict + + def group(self, *args): + """Returns one or more subgroups of the match. Each argument is either a + group index or a group name.""" + if len(args) == 0: + args = (0,) + grouplist = [] + for group in args: + grouplist.append(self._get_slice(self._get_index(group), None)) + if len(grouplist) == 1: + return grouplist[0] + else: + return tuple(grouplist) + + def __copy__(): + raise TypeError, "cannot copy this pattern object" + + def __deepcopy__(): + raise TypeError, "cannot copy this pattern object" + + +class _State(object): + + def __init__(self, string, start, end, flags): + self.string = string + if start < 0: + start = 0 + if end > len(string): + end = len(string) + self.start = start + self.string_position = self.start + self.end = end + self.pos = start + self.flags = flags + self.reset() + + def reset(self): + self.marks = [] + self.lastindex = -1 + self.marks_stack = [] + self.context_stack = [] + self.repeat = None + + def match(self, pattern_codes): + # Optimization: Check string length. pattern_codes[3] contains the + # minimum length for a string to possibly match. + if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: + if self.end - self.string_position < pattern_codes[3]: + #_log("reject (got %d chars, need %d)" + # % (self.end - self.string_position, pattern_codes[3])) + return False + + dispatcher = _OpcodeDispatcher() + self.context_stack.append(_MatchContext(self, pattern_codes)) + has_matched = None + while len(self.context_stack) > 0: + context = self.context_stack[-1] + has_matched = dispatcher.match(context) + if has_matched is not None: # don't pop if context isn't done + self.context_stack.pop() + return has_matched + + def search(self, pattern_codes): + flags = 0 + if pattern_codes[0] == OPCODES["info"]: + # optimization info block + # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> + if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: + return self.fast_search(pattern_codes) + flags = pattern_codes[2] + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + + string_position = self.start + if pattern_codes[0] == OPCODES["literal"]: + # Special case: Pattern starts with a literal character. This is + # used for short prefixes + character = pattern_codes[1] + while True: + while string_position < self.end \ + and ord(self.string[string_position]) != character: + string_position += 1 + if string_position >= self.end: + return False + self.start = string_position + string_position += 1 + self.string_position = string_position + if flags & SRE_INFO_LITERAL: + return True + if self.match(pattern_codes[2:]): + return True + return False + + # General case + while string_position <= self.end: + self.reset() + self.start = self.string_position = string_position + if self.match(pattern_codes): + return True + string_position += 1 + return False + + def fast_search(self, pattern_codes): + """Skips forward in a string as fast as possible using information from + an optimization info block.""" + # pattern starts with a known prefix + # <5=length> <6=skip> <7=prefix data> + flags = pattern_codes[2] + prefix_len = pattern_codes[5] + prefix_skip = pattern_codes[6] # don't really know what this is good for + prefix = pattern_codes[7:7 + prefix_len] + overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + i = 0 + string_position = self.string_position + while string_position < self.end: + while True: + if ord(self.string[string_position]) != prefix[i]: + if i == 0: + break + else: + i = overlap[i] + else: + i += 1 + if i == prefix_len: + # found a potential match + self.start = string_position + 1 - prefix_len + self.string_position = string_position + 1 \ + - prefix_len + prefix_skip + if flags & SRE_INFO_LITERAL: + return True # matched all of pure literal pattern + if self.match(pattern_codes[2 * prefix_skip:]): + return True + i = overlap[i] + break + string_position += 1 + return False + + def set_mark(self, mark_nr, position): + if mark_nr & 1: + # This id marks the end of a group. + self.lastindex = mark_nr / 2 + 1 + if mark_nr >= len(self.marks): + self.marks.extend([None] * (mark_nr - len(self.marks) + 1)) + self.marks[mark_nr] = position + + def get_marks(self, group_index): + marks_index = 2 * group_index + if len(self.marks) > marks_index + 1: + return self.marks[marks_index], self.marks[marks_index + 1] + else: + return None, None + + def marks_push(self): + self.marks_stack.append((self.marks[:], self.lastindex)) + + def marks_pop(self): + self.marks, self.lastindex = self.marks_stack.pop() + + def marks_pop_keep(self): + self.marks, self.lastindex = self.marks_stack[-1] + + def marks_pop_discard(self): + self.marks_stack.pop() + + def lower(self, char_ord): + return getlower(char_ord, self.flags) + + +class _MatchContext(object): + + def __init__(self, state, pattern_codes): + self.state = state + self.pattern_codes = pattern_codes + self.string_position = state.string_position + self.code_position = 0 + self.has_matched = None + + def push_new_context(self, pattern_offset): + """Creates a new child context of this context and pushes it on the + stack. pattern_offset is the offset off the current code position to + start interpreting from.""" + child_context = _MatchContext(self.state, + self.pattern_codes[self.code_position + pattern_offset:]) + self.state.context_stack.append(child_context) + return child_context + + def peek_char(self, peek=0): + return self.state.string[self.string_position + peek] + + def skip_char(self, skip_count): + self.string_position += skip_count + + def remaining_chars(self): + return self.state.end - self.string_position + + def peek_code(self, peek=0): + return self.pattern_codes[self.code_position + peek] + + def skip_code(self, skip_count): + self.code_position += skip_count + + def remaining_codes(self): + return len(self.pattern_codes) - self.code_position + + def at_beginning(self): + return self.string_position == 0 + + def at_end(self): + return self.string_position == self.state.end + + def at_linebreak(self): + return not self.at_end() and _is_linebreak(self.peek_char()) + + def at_boundary(self, word_checker): + if self.at_beginning() and self.at_end(): + return False + that = not self.at_beginning() and word_checker(self.peek_char(-1)) + this = not self.at_end() and word_checker(self.peek_char()) + return this != that + + +class _RepeatContext(_MatchContext): + + def __init__(self, context): + _MatchContext.__init__(self, context.state, + context.pattern_codes[context.code_position:]) + self.count = -1 + self.previous = context.state.repeat + self.last_position = None + + +class _Dispatcher(object): + + DISPATCH_TABLE = None + + def dispatch(self, code, context): + method = self.DISPATCH_TABLE.get(code, self.__class__.unknown) + return method(self, context) + + def unknown(self, code, ctx): + raise NotImplementedError() + + def build_dispatch_table(cls, code_dict, method_prefix): + if cls.DISPATCH_TABLE is not None: + return + table = {} + for key, value in code_dict.items(): + if hasattr(cls, "%s%s" % (method_prefix, key)): + table[value] = getattr(cls, "%s%s" % (method_prefix, key)) + cls.DISPATCH_TABLE = table + + build_dispatch_table = classmethod(build_dispatch_table) + + +class _OpcodeDispatcher(_Dispatcher): + + def __init__(self): + self.executing_contexts = {} + self.at_dispatcher = _AtcodeDispatcher() + self.ch_dispatcher = _ChcodeDispatcher() + self.set_dispatcher = _CharsetDispatcher() + + def match(self, context): + """Returns True if the current context matches, False if it doesn't and + None if matching is not finished, ie must be resumed after child + contexts have been matched.""" + while context.remaining_codes() > 0 and context.has_matched is None: + opcode = context.peek_code() + if not self.dispatch(opcode, context): + return None + if context.has_matched is None: + context.has_matched = False + return context.has_matched + + 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)] + has_finished = generator.next() + else: + method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown) + has_finished = method(self, context) + if hasattr(has_finished, "next"): # avoid using the types module + generator = has_finished + has_finished = generator.next() + if not has_finished: + self.executing_contexts[id(context)] = generator + return has_finished + + def op_success(self, ctx): + # end of pattern + #self._log(ctx, "SUCCESS") + ctx.state.string_position = ctx.string_position + ctx.has_matched = True + return True + + def op_failure(self, ctx): + # immediate failure + #self._log(ctx, "FAILURE") + ctx.has_matched = False + return True + + def general_op_literal(self, ctx, compare, decorate=lambda x: x): + if ctx.at_end() or not compare(decorate(ord(ctx.peek_char())), + decorate(ctx.peek_code(1))): + ctx.has_matched = False + ctx.skip_code(2) + ctx.skip_char(1) + + def op_literal(self, ctx): + # match literal string + # + #self._log(ctx, "LITERAL", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.eq) + return True + + def op_not_literal(self, ctx): + # match anything that is not the given literal character + # + #self._log(ctx, "NOT_LITERAL", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.ne) + return True + + def op_literal_ignore(self, ctx): + # match literal regardless of case + # + #self._log(ctx, "LITERAL_IGNORE", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.eq, ctx.state.lower) + return True + + def op_not_literal_ignore(self, ctx): + # match literal regardless of case + # + #self._log(ctx, "LITERAL_IGNORE", ctx.peek_code(1)) + self.general_op_literal(ctx, operator.ne, ctx.state.lower) + return True + + def op_at(self, ctx): + # match at given position + # + #self._log(ctx, "AT", ctx.peek_code(1)) + if not self.at_dispatcher.dispatch(ctx.peek_code(1), ctx): + ctx.has_matched = False + return True + ctx.skip_code(2) + return True + + def op_category(self, ctx): + # match at given category + # + #self._log(ctx, "CATEGORY", ctx.peek_code(1)) + if ctx.at_end() or not self.ch_dispatcher.dispatch(ctx.peek_code(1), ctx): + ctx.has_matched = False + return True + ctx.skip_code(2) + ctx.skip_char(1) + return True + + def op_any(self, ctx): + # match anything (except a newline) + # + #self._log(ctx, "ANY") + if ctx.at_end() or ctx.at_linebreak(): + ctx.has_matched = False + return True + ctx.skip_code(1) + ctx.skip_char(1) + return True + + def op_any_all(self, ctx): + # match anything + # + #self._log(ctx, "ANY_ALL") + if ctx.at_end(): + ctx.has_matched = False + return True + ctx.skip_code(1) + ctx.skip_char(1) + return True + + def general_op_in(self, ctx, decorate=lambda x: x): + #self._log(ctx, "OP_IN") + if ctx.at_end(): + ctx.has_matched = False + return + skip = ctx.peek_code(1) + ctx.skip_code(2) # set op pointer to the set code + if not self.check_charset(ctx, decorate(ord(ctx.peek_char()))): + ctx.has_matched = False + return + ctx.skip_code(skip - 1) + ctx.skip_char(1) + + def op_in(self, ctx): + # match set member (or non_member) + # + #self._log(ctx, "OP_IN") + self.general_op_in(ctx) + return True + + def op_in_ignore(self, ctx): + # match set member (or non_member), disregarding case of current char + # + #self._log(ctx, "OP_IN_IGNORE") + self.general_op_in(ctx, ctx.state.lower) + return True + + def op_jump(self, ctx): + # jump forward + # + #self._log(ctx, "JUMP", ctx.peek_code(1)) + ctx.skip_code(ctx.peek_code(1) + 1) + return True + + # skip info + # + op_info = op_jump + + def op_mark(self, ctx): + # set mark + # + #self._log(ctx, "OP_MARK", ctx.peek_code(1)) + ctx.state.set_mark(ctx.peek_code(1), ctx.string_position) + ctx.skip_code(2) + return True + + def op_branch(self, ctx): + # alternation + # <0=skip> code ... + #self._log(ctx, "BRANCH") + ctx.state.marks_push() + ctx.skip_code(1) + current_branch_length = ctx.peek_code(0) + while current_branch_length: + # The following tries to shortcut branches starting with a + # (unmatched) literal. _sre.c also shortcuts charsets here. + if not (ctx.peek_code(1) == OPCODES["literal"] and \ + (ctx.at_end() or ctx.peek_code(2) != ord(ctx.peek_char()))): + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.state.marks_pop_keep() + ctx.skip_code(current_branch_length) + current_branch_length = ctx.peek_code(0) + ctx.state.marks_pop_discard() + ctx.has_matched = False + yield True + + def op_repeat_one(self, ctx): + # match repeated sequence (maximizing). + # this operator only works if the repeated item is exactly one character + # wide, and we're not already collecting backtracking points. + # <1=min> <2=max> item tail + mincount = ctx.peek_code(2) + maxcount = ctx.peek_code(3) + #self._log(ctx, "REPEAT_ONE", mincount, maxcount) + + if ctx.remaining_chars() < mincount: + ctx.has_matched = False + yield True + ctx.state.string_position = ctx.string_position + count = self.count_repetitions(ctx, maxcount) + ctx.skip_char(count) + if count < mincount: + ctx.has_matched = False + yield True + if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: + # tail is empty. we're finished + ctx.state.string_position = ctx.string_position + ctx.has_matched = True + yield True + + ctx.state.marks_push() + if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["literal"]: + # Special case: Tail starts with a literal. Skip positions where + # the rest of the pattern cannot possibly match. + char = ctx.peek_code(ctx.peek_code(1) + 2) + while True: + while count >= mincount and \ + (ctx.at_end() or ord(ctx.peek_char()) != char): + ctx.skip_char(-1) + count -= 1 + if count < mincount: + break + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.skip_char(-1) + count -= 1 + ctx.state.marks_pop_keep() + + else: + # General case: backtracking + while count >= mincount: + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.skip_char(-1) + count -= 1 + ctx.state.marks_pop_keep() + + ctx.state.marks_pop_discard() + ctx.has_matched = False + yield True + + def op_min_repeat_one(self, ctx): + # match repeated sequence (minimizing) + # <1=min> <2=max> item tail + mincount = ctx.peek_code(2) + maxcount = ctx.peek_code(3) + #self._log(ctx, "MIN_REPEAT_ONE", mincount, maxcount) + + if ctx.remaining_chars() < mincount: + ctx.has_matched = False + yield True + ctx.state.string_position = ctx.string_position + if mincount == 0: + count = 0 + else: + count = self.count_repetitions(ctx, mincount) + if count < mincount: + ctx.has_matched = False + yield True + ctx.skip_char(count) + if ctx.peek_code(ctx.peek_code(1) + 1) == OPCODES["success"]: + # tail is empty. we're finished + ctx.state.string_position = ctx.string_position + ctx.has_matched = True + yield True + + ctx.state.marks_push() + while maxcount == MAXREPEAT or count <= maxcount: + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.state.string_position = ctx.string_position + if self.count_repetitions(ctx, 1) == 0: + break + ctx.skip_char(1) + count += 1 + ctx.state.marks_pop_keep() + + ctx.state.marks_pop_discard() + ctx.has_matched = False + yield True + + def op_repeat(self, ctx): + # create repeat context. all the hard work is done by the UNTIL + # operator (MAX_UNTIL, MIN_UNTIL) + # <1=min> <2=max> item tail + #self._log(ctx, "REPEAT", ctx.peek_code(2), ctx.peek_code(3)) + repeat = _RepeatContext(ctx) + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + child_context = ctx.push_new_context(ctx.peek_code(1) + 1) + yield False + ctx.state.repeat = repeat.previous + ctx.has_matched = child_context.has_matched + yield True + + def op_max_until(self, ctx): + # maximizing repeat + # <1=min> <2=max> item tail + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + #self._log(ctx, "MAX_UNTIL", count) + + if count < mincount: + # not enough matches + repeat.count = count + child_context = repeat.push_new_context(4) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + yield True + + if (count < maxcount or maxcount == MAXREPEAT) \ + and ctx.state.string_position != repeat.last_position: + # we may have enough matches, if we can match another item, do so + repeat.count = count + ctx.state.marks_push() + save_last_position = repeat.last_position # zero-width match protection + repeat.last_position = ctx.state.string_position + child_context = repeat.push_new_context(4) + yield False + repeat.last_position = save_last_position + if child_context.has_matched: + ctx.state.marks_pop_discard() + ctx.has_matched = True + yield True + ctx.state.marks_pop() + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + + # cannot match more repeated items here. make sure the tail matches + ctx.state.repeat = repeat.previous + child_context = ctx.push_new_context(1) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + yield True + + def op_min_until(self, ctx): + # minimizing repeat + # <1=min> <2=max> item tail + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + #self._log(ctx, "MIN_UNTIL", count) + + if count < mincount: + # not enough matches + repeat.count = count + child_context = repeat.push_new_context(4) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + yield True + + # see if the tail matches + ctx.state.marks_push() + ctx.state.repeat = repeat.previous + child_context = ctx.push_new_context(1) + yield False + if child_context.has_matched: + ctx.has_matched = True + yield True + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + ctx.state.marks_pop() + + # match more until tail matches + if count >= maxcount and maxcount != MAXREPEAT: + ctx.has_matched = False + yield True + repeat.count = count + child_context = repeat.push_new_context(4) + yield False + ctx.has_matched = child_context.has_matched + if not ctx.has_matched: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + yield True + + def general_op_groupref(self, ctx, decorate=lambda x: x): + group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) + if group_start is None or group_end is None or group_end < group_start: + ctx.has_matched = False + return True + while group_start < group_end: + if ctx.at_end() or decorate(ord(ctx.peek_char())) \ + != decorate(ord(ctx.state.string[group_start])): + ctx.has_matched = False + return True + group_start += 1 + ctx.skip_char(1) + ctx.skip_code(2) + return True + + def op_groupref(self, ctx): + # match backreference + # + #self._log(ctx, "GROUPREF", ctx.peek_code(1)) + return self.general_op_groupref(ctx) + + def op_groupref_ignore(self, ctx): + # match backreference case-insensitive + # + #self._log(ctx, "GROUPREF_IGNORE", ctx.peek_code(1)) + return self.general_op_groupref(ctx, ctx.state.lower) + + def op_groupref_exists(self, ctx): + # codeyes codeno ... + #self._log(ctx, "GROUPREF_EXISTS", ctx.peek_code(1)) + group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) + if group_start is None or group_end is None or group_end < group_start: + ctx.skip_code(ctx.peek_code(2) + 1) + else: + ctx.skip_code(3) + return True + + def op_assert(self, ctx): + # assert subpattern + # + #self._log(ctx, "ASSERT", ctx.peek_code(2)) + ctx.state.string_position = ctx.string_position - ctx.peek_code(2) + if ctx.state.string_position < 0: + ctx.has_matched = False + yield True + child_context = ctx.push_new_context(3) + yield False + if child_context.has_matched: + ctx.skip_code(ctx.peek_code(1) + 1) + else: + ctx.has_matched = False + yield True + + def op_assert_not(self, ctx): + # assert not subpattern + # + #self._log(ctx, "ASSERT_NOT", ctx.peek_code(2)) + ctx.state.string_position = ctx.string_position - ctx.peek_code(2) + if ctx.state.string_position >= 0: + child_context = ctx.push_new_context(3) + yield False + if child_context.has_matched: + ctx.has_matched = False + yield True + ctx.skip_code(ctx.peek_code(1) + 1) + yield True + + def unknown(self, ctx): + #self._log(ctx, "UNKNOWN", ctx.peek_code()) + raise RuntimeError("Internal re error. Unknown opcode: %s" % ctx.peek_code()) + + def check_charset(self, ctx, char): + """Checks whether a character matches set of arbitrary length. Assumes + the code pointer is at the first member of the set.""" + self.set_dispatcher.reset(char) + save_position = ctx.code_position + result = None + while result is None: + result = self.set_dispatcher.dispatch(ctx.peek_code(), ctx) + ctx.code_position = save_position + return result + + def count_repetitions(self, ctx, maxcount): + """Returns the number of repetitions of a single item, starting from the + current string position. The code pointer is expected to point to a + REPEAT_ONE operation (with the repeated 4 ahead).""" + count = 0 + real_maxcount = ctx.state.end - ctx.string_position + if maxcount < real_maxcount and maxcount != MAXREPEAT: + real_maxcount = maxcount + # XXX could special case every single character pattern here, as in C. + # This is a general solution, a bit hackisch, but works and should be + # efficient. + code_position = ctx.code_position + string_position = ctx.string_position + ctx.skip_code(4) + reset_position = ctx.code_position + while count < real_maxcount: + # this works because the single character pattern is followed by + # a success opcode + ctx.code_position = reset_position + self.dispatch(ctx.peek_code(), ctx) + if ctx.has_matched is False: # could be None as well + break + count += 1 + ctx.has_matched = None + ctx.code_position = code_position + ctx.string_position = string_position + return count + + def _log(self, context, opname, *args): + arg_string = ("%s " * len(args)) % args + _log("|%s|%s|%s %s" % (context.pattern_codes, + context.string_position, opname, arg_string)) + +_OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") + + +class _CharsetDispatcher(_Dispatcher): + + def __init__(self): + self.ch_dispatcher = _ChcodeDispatcher() + + def reset(self, char): + self.char = char + self.ok = True + + def set_failure(self, ctx): + return not self.ok + def set_literal(self, ctx): + # + if ctx.peek_code(1) == self.char: + return self.ok + else: + ctx.skip_code(2) + def set_category(self, ctx): + # + if self.ch_dispatcher.dispatch(ctx.peek_code(1), ctx): + return self.ok + else: + ctx.skip_code(2) + def set_charset(self, ctx): + # (16 bits per code word) + char_code = self.char + ctx.skip_code(1) # point to beginning of bitmap + if CODESIZE == 2: + if char_code < 256 and ctx.peek_code(char_code >> 4) \ + & (1 << (char_code & 15)): + return self.ok + ctx.skip_code(16) # skip bitmap + else: + if char_code < 256 and ctx.peek_code(char_code >> 5) \ + & (1 << (char_code & 31)): + return self.ok + ctx.skip_code(8) # skip bitmap + def set_range(self, ctx): + # + if ctx.peek_code(1) <= self.char <= ctx.peek_code(2): + return self.ok + ctx.skip_code(3) + def set_negate(self, ctx): + self.ok = not self.ok + ctx.skip_code(1) + def set_bigcharset(self, ctx): + # <256 blockindices> + char_code = self.char + count = ctx.peek_code(1) + ctx.skip_code(2) + if char_code < 65536: + block_index = char_code >> 8 + # NB: there are CODESIZE block indices per bytecode + a = array.array("B") + a.fromstring(array.array(CODESIZE == 2 and "H" or "I", + [ctx.peek_code(block_index / CODESIZE)]).tostring()) + block = a[block_index % CODESIZE] + ctx.skip_code(256 / CODESIZE) # skip block indices + block_value = ctx.peek_code(block * (32 / CODESIZE) + + ((char_code & 255) >> (CODESIZE == 2 and 4 or 5))) + if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): + return self.ok + else: + ctx.skip_code(256 / CODESIZE) # skip block indices + ctx.skip_code(count * (32 / CODESIZE)) # skip blocks + def unknown(self, ctx): + return False + +_CharsetDispatcher.build_dispatch_table(OPCODES, "set_") + + +class _AtcodeDispatcher(_Dispatcher): + + def at_beginning(self, ctx): + return ctx.at_beginning() + at_beginning_string = at_beginning + def at_beginning_line(self, ctx): + return ctx.at_beginning() or _is_linebreak(ctx.peek_char(-1)) + def at_end(self, ctx): + return (ctx.remaining_chars() == 1 and ctx.at_linebreak()) or ctx.at_end() + def at_end_line(self, ctx): + return ctx.at_linebreak() or ctx.at_end() + def at_end_string(self, ctx): + return ctx.at_end() + def at_boundary(self, ctx): + return ctx.at_boundary(_is_word) + def at_non_boundary(self, ctx): + return not ctx.at_boundary(_is_word) + def at_loc_boundary(self, ctx): + return ctx.at_boundary(_is_loc_word) + def at_loc_non_boundary(self, ctx): + return not ctx.at_boundary(_is_loc_word) + def at_uni_boundary(self, ctx): + return ctx.at_boundary(_is_uni_word) + def at_uni_non_boundary(self, ctx): + return not ctx.at_boundary(_is_uni_word) + def unknown(self, ctx): + return False + +_AtcodeDispatcher.build_dispatch_table(ATCODES, "") + + +class _ChcodeDispatcher(_Dispatcher): + + def category_digit(self, ctx): + return _is_digit(ctx.peek_char()) + def category_not_digit(self, ctx): + return not _is_digit(ctx.peek_char()) + def category_space(self, ctx): + return _is_space(ctx.peek_char()) + def category_not_space(self, ctx): + return not _is_space(ctx.peek_char()) + def category_word(self, ctx): + return _is_word(ctx.peek_char()) + def category_not_word(self, ctx): + return not _is_word(ctx.peek_char()) + def category_linebreak(self, ctx): + return _is_linebreak(ctx.peek_char()) + def category_not_linebreak(self, ctx): + return not _is_linebreak(ctx.peek_char()) + def category_loc_word(self, ctx): + return _is_loc_word(ctx.peek_char()) + def category_loc_not_word(self, ctx): + return not _is_loc_word(ctx.peek_char()) + def category_uni_digit(self, ctx): + return ctx.peek_char().isdigit() + def category_uni_not_digit(self, ctx): + return not ctx.peek_char().isdigit() + def category_uni_space(self, ctx): + return ctx.peek_char().isspace() + def category_uni_not_space(self, ctx): + return not ctx.peek_char().isspace() + def category_uni_word(self, ctx): + return _is_uni_word(ctx.peek_char()) + def category_uni_not_word(self, ctx): + return not _is_uni_word(ctx.peek_char()) + def category_uni_linebreak(self, ctx): + return ord(ctx.peek_char()) in _uni_linebreaks + def category_uni_not_linebreak(self, ctx): + return ord(ctx.peek_char()) not in _uni_linebreaks + def unknown(self, ctx): + return False + +_ChcodeDispatcher.build_dispatch_table(CHCODES, "") + + +_ascii_char_info = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, +2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, +0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 ] + +def _is_digit(char): + code = ord(char) + return code < 128 and _ascii_char_info[code] & 1 + +def _is_space(char): + code = ord(char) + return code < 128 and _ascii_char_info[code] & 2 + +def _is_word(char): + # NB: non-ASCII chars aren't words according to _sre.c + code = ord(char) + return code < 128 and _ascii_char_info[code] & 16 + +def _is_loc_word(char): + return (not (ord(char) & ~255) and char.isalnum()) or char == '_' + +def _is_uni_word(char): + return unichr(ord(char)).isalnum() or char == '_' + +def _is_linebreak(char): + return char == "\n" + +# Static list of all unicode codepoints reported by Py_UNICODE_ISLINEBREAK. +_uni_linebreaks = [10, 13, 28, 29, 30, 133, 8232, 8233] + +def _log(message): + if 0: + print message From arigo at codespeak.net Fri Aug 26 13:16:15 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 13:16:15 +0200 (CEST) Subject: [pypy-svn] r16600 - pypy/dist/pypy/translator/goal Message-ID: <20050826111615.79DF827B47@code1.codespeak.net> Author: arigo Date: Fri Aug 26 13:16:14 2005 New Revision: 16600 Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: Enable threads in the translated PyPy by default. Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Fri Aug 26 13:16:14 2005 @@ -51,7 +51,7 @@ space = StdObjSpace(nofaking=True, compiler="pyparseapp", translating=True, - #usemodules=['marshal', '_sre'], + usemodules=['thread'], geninterp=geninterp) # manually imports app_main.py filename = os.path.join(this_dir, 'app_main.py') From nik at codespeak.net Fri Aug 26 13:18:03 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 13:18:03 +0200 (CEST) Subject: [pypy-svn] r16601 - pypy/dist/pypy/module/_sre Message-ID: <20050826111803.A122327B47@code1.codespeak.net> Author: nik Date: Fri Aug 26 13:18:02 2005 New Revision: 16601 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved op_assert and op_assert_not to interp-level. Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 26 13:18:02 2005 @@ -566,36 +566,6 @@ repeat.count = count - 1 ctx.state.string_position = ctx.string_position yield True - - def op_assert(self, ctx): - # assert subpattern - # - #self._log(ctx, "ASSERT", ctx.peek_code(2)) - ctx.state.string_position = ctx.string_position - ctx.peek_code(2) - if ctx.state.string_position < 0: - ctx.has_matched = NOT_MATCHED - yield True - child_context = ctx.push_new_context(3) - yield False - if child_context.has_matched == MATCHED: - ctx.skip_code(ctx.peek_code(1) + 1) - else: - ctx.has_matched = NOT_MATCHED - yield True - - def op_assert_not(self, ctx): - # assert not subpattern - # - #self._log(ctx, "ASSERT_NOT", ctx.peek_code(2)) - ctx.state.string_position = ctx.string_position - ctx.peek_code(2) - if ctx.state.string_position >= 0: - child_context = ctx.push_new_context(3) - yield False - if child_context.has_matched == MATCHED: - ctx.has_matched = NOT_MATCHED - yield True - ctx.skip_code(ctx.peek_code(1) + 1) - yield True def unknown(self, ctx): #self._log(ctx, "UNKNOWN", ctx.peek_code()) Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 13:18:02 2005 @@ -319,6 +319,7 @@ if not has_finished: context.resume_at_opcode = opcode return context.UNDECIDED + context.resume_at_opcode = -1 if context.has_matched == context.UNDECIDED: context.has_matched = context.NOT_MATCHED return context.has_matched @@ -629,7 +630,7 @@ # return general_op_groupref(space, ctx, ignore=True) -def op_groupref_exists(self, ctx): +def op_groupref_exists(space, ctx): # codeyes codeno ... group_start, group_end = ctx.state.get_marks(ctx.peek_code(1)) if group_start == -1 or group_end == -1 or group_end < group_start: @@ -638,6 +639,38 @@ ctx.skip_code(3) return True +def op_assert(space, ctx): + # assert subpattern + # + if not ctx.is_resumed(): + ctx.state.string_position = ctx.string_position - ctx.peek_code(2) + if ctx.state.string_position < 0: + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.push_new_context(3) + return False + else: + if ctx.child_context.has_matched == ctx.MATCHED: + ctx.skip_code(ctx.peek_code(1) + 1) + else: + ctx.has_matched = ctx.NOT_MATCHED + return True + +def op_assert_not(space, ctx): + # assert not subpattern + # + if not ctx.is_resumed(): + ctx.state.string_position = ctx.string_position - ctx.peek_code(2) + if ctx.state.string_position >= 0: + ctx.push_new_context(3) + return False + else: + if ctx.child_context.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.NOT_MATCHED + return True + ctx.skip_code(ctx.peek_code(1) + 1) + return True + def count_repetitions(space, ctx, maxcount): """Returns the number of repetitions of a single item, starting from the current string position. The code pointer is expected to point to a @@ -669,7 +702,7 @@ opcode_dispatch_table = [ op_failure, op_success, op_any, op_any_all, - None, None, #ASSERT, ASSERT_NOT, + op_assert, op_assert_not, op_at, op_branch, None, #CALL, From hpk at codespeak.net Fri Aug 26 13:23:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 13:23:06 +0200 (CEST) Subject: [pypy-svn] r16602 - pypy/dist/lib-python Message-ID: <20050826112306.7C0DD27B47@code1.codespeak.net> Author: hpk Date: Fri Aug 26 13:23:05 2005 New Revision: 16602 Modified: pypy/dist/lib-python/conftest.py Log: use posix module when running file tests Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Aug 26 13:23:05 2005 @@ -484,7 +484,7 @@ RegrTest('test_exceptions.py', enabled=True, core=True), RegrTest('test_extcall.py', enabled=True, core=True), RegrTest('test_fcntl.py', enabled=False, dumbtest=1), - RegrTest('test_file.py', enabled=True, dumbtest=1, core=True, uselibfile=True), + RegrTest('test_file.py', enabled=True, dumbtest=1, usemodules="posix", core=True, uselibfile=True), RegrTest('test_filecmp.py', enabled=True, core=True), RegrTest('test_fileinput.py', enabled=True, dumbtest=1, core=True), RegrTest('test_fnmatch.py', enabled=True, core=True), From pedronis at codespeak.net Fri Aug 26 13:29:45 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 13:29:45 +0200 (CEST) Subject: [pypy-svn] r16604 - pypy/dist/pypy/interpreter/test Message-ID: <20050826112945.81ECC27B47@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 13:29:44 2005 New Revision: 16604 Added: pypy/dist/pypy/interpreter/test/test_syntax.py - copied unchanged from r16603, pypy/dist/pypy/interpreter/test/inprogress_test_syntax.py Removed: pypy/dist/pypy/interpreter/test/inprogress_test_syntax.py Log: completely passing now, rename From nik at codespeak.net Fri Aug 26 13:32:25 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 13:32:25 +0200 (CEST) Subject: [pypy-svn] r16605 - pypy/dist/pypy/module/_sre/test Message-ID: <20050826113225.1E0C527B4B@code1.codespeak.net> Author: nik Date: Fri Aug 26 13:32:24 2005 New Revision: 16605 Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py Log: adapt interp-level tests to new interface of interp_sre.py. passes again. Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Fri Aug 26 13:32:24 2005 @@ -7,6 +7,12 @@ EM_SPACE = u"\u2001" INDIAN_DIGIT = u"\u0966" +def create_context(space, string, string_position, end): + state = isre.W_State(space, space.wrap(string), space.wrap(0), + space.wrap(end), space.wrap(0)) + state.string_position = string_position + return isre.W_MatchContext(space, state, space.newlist([])) + def test_is_uni_linebreak(space): for char in ["\n", "\r"]: assert isre.is_uni_linebreak(space, space.wrap(char)) @@ -51,33 +57,24 @@ assert not isre.is_uni_space(space, space.wrap(char)) def test_at_beginning(space): - assert isre.at_beginning(space, - isre.MatchContext(space, [], space.wrap(""), 0, 0)) - assert not isre.at_beginning(space, - isre.MatchContext(space, [], space.wrap("a"), 1, 1)) + assert isre.at_beginning(space, create_context(space, "", 0, 0)) + assert not isre.at_beginning(space, create_context(space, "a", 1, 1)) def test_at_beginning_line(space): - assert isre.at_beginning_line(space, - isre.MatchContext(space, [], space.wrap(""), 0, 0)) - assert isre.at_beginning_line(space, - isre.MatchContext(space, [], space.wrap("\na"), 1, 3)) - assert not isre.at_beginning_line(space, - isre.MatchContext(space, [], space.wrap("a"), 1, 2)) + assert isre.at_beginning_line(space, create_context(space, "", 0, 0)) + assert isre.at_beginning_line(space, create_context(space, "\na", 1, 3)) + assert not isre.at_beginning_line(space, create_context(space, "a", 1, 2)) def test_at_end(space): for string, pos, end in [("", 0, 0), ("a", 1, 1), ("a\n", 1, 2)]: - assert isre.at_end(space, - isre.MatchContext(space, [], space.wrap(string), pos, end)) - assert not isre.at_end(space, - isre.MatchContext(space, [], space.wrap("a"), 0, 1)) + assert isre.at_end(space, create_context(space, string, pos, end)) + assert not isre.at_end(space, create_context(space, "a", 0, 1)) def test_at_boundary(space): for string, pos, end in [("a.", 1, 2), (".a", 1, 2)]: - assert isre.at_boundary(space, - isre.MatchContext(space, [], space.wrap(string), pos, end)) + assert isre.at_boundary(space, create_context(space, string, pos, end)) for string, pos, end in [(".", 0, 1), (".", 1, 1), ("ab", 1, 2)]: - assert not isre.at_boundary(space, - isre.MatchContext(space, [], space.wrap(string), pos, end)) + assert not isre.at_boundary(space, create_context(space, string, pos, end)) def test_getlower(space): assert space.int_w(isre.getlower(space, space.wrap(ord("A")), space.wrap(0))) == ord("a") From cfbolz at codespeak.net Fri Aug 26 13:36:56 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 13:36:56 +0200 (CEST) Subject: [pypy-svn] r16606 - pypy/dist/pypy/doc/image Message-ID: <20050826113656.6256C27B4B@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 13:36:55 2005 New Revision: 16606 Modified: pypy/dist/pypy/doc/image/translation.sxd Log: updated the translation process graph Modified: pypy/dist/pypy/doc/image/translation.sxd ============================================================================== Binary files. No diff available. From cfbolz at codespeak.net Fri Aug 26 13:37:39 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 13:37:39 +0200 (CEST) Subject: [pypy-svn] r16607 - pypy/dist/pypy/doc/image Message-ID: <20050826113739.9A30E27B4B@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 13:37:37 2005 New Revision: 16607 Modified: pypy/dist/pypy/doc/image/translation.sxd Log: oops, bug: one string was italic Modified: pypy/dist/pypy/doc/image/translation.sxd ============================================================================== Binary files. No diff available. From pedronis at codespeak.net Fri Aug 26 13:41:52 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 13:41:52 +0200 (CEST) Subject: [pypy-svn] r16609 - pypy/dist/pypy/interpreter Message-ID: <20050826114152.2BFB027B52@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 13:41:50 2005 New Revision: 16609 Modified: pypy/dist/pypy/interpreter/baseobjspace.py Log: enable our own math module by default Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Fri Aug 26 13:41:50 2005 @@ -170,11 +170,10 @@ pass modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', - 'array', 'marshal', 'errno'] + 'array', 'marshal', 'errno', 'math'] if self.options.nofaking: modules.append('posix') - modules.append('math') modules.append('time') modules.append('errno') From tismer at codespeak.net Fri Aug 26 13:50:16 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 13:50:16 +0200 (CEST) Subject: [pypy-svn] r16610 - pypy/dist/pypy/translator/c/src Message-ID: <20050826115016.A2A2927B52@code1.codespeak.net> Author: tismer Date: Fri Aug 26 13:50:15 2005 New Revision: 16610 Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: forgot the mode parameter for mkdir in the low level implementation. Funny, becasue I knew ti and dit it correctty, everywhere else. The bad thing is that windows didn't complain about the missing arg :-( Modified: pypy/dist/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_os.h (original) +++ pypy/dist/pypy/translator/c/src/ll_os.h Fri Aug 26 13:50:15 2005 @@ -198,8 +198,8 @@ } } -void LL_os_mkdir(RPyString * path) { - int error = mkdir(RPyString_AsString(path)); +void LL_os_mkdir(RPyString * path, int mode) { + int error = mkdir(RPyString_AsString(path), mode); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } From arigo at codespeak.net Fri Aug 26 13:56:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 13:56:30 +0200 (CEST) Subject: [pypy-svn] r16611 - in pypy/dist/pypy/interpreter: pyparser test Message-ID: <20050826115630.A2ADB27B52@code1.codespeak.net> Author: arigo Date: Fri Aug 26 13:56:30 2005 New Revision: 16611 Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py pypy/dist/pypy/interpreter/test/test_compiler.py pypy/dist/pypy/interpreter/test/test_exec.py Log: Some more pushing-and-pulling to make the interactive command line behave. Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonparse.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonparse.py Fri Aug 26 13:56:30 2005 @@ -31,9 +31,6 @@ if textsrc.endswith('\n'): lines.pop() flags &= ~PyCF_DONT_IMPLY_DEDENT - else: - last_line = lines[-1] - lines[-1] = last_line[:-1] return self.parse_lines(lines, goal, builder, flags) def parse_lines(self, lines, goal, builder, flags=0): Modified: pypy/dist/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_compiler.py (original) +++ pypy/dist/pypy/interpreter/test/test_compiler.py Fri Aug 26 13:56:30 2005 @@ -27,9 +27,13 @@ c0 = self.compiler.compile_command('\t # hello\n ', '?', mode, 0) c1 = self.compiler.compile_command('print 6*7', '?', mode, 0) c2 = self.compiler.compile_command('if 1:\n x\n', '?', mode, 0) + c8 = self.compiler.compile_command('x = 5', '?', mode, 0) + c9 = self.compiler.compile_command('x = 5 ', '?', mode, 0) assert c0 is not None assert c1 is not None assert c2 is not None + assert c8 is not None + assert c9 is not None c3 = self.compiler.compile_command('if 1:\n x', '?', mode, 0) c4 = self.compiler.compile_command('x = (', '?', mode, 0) c5 = self.compiler.compile_command('x = (\n', '?', mode, 0) Modified: pypy/dist/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_exec.py (original) +++ pypy/dist/pypy/interpreter/test/test_exec.py Fri Aug 26 13:56:30 2005 @@ -169,3 +169,8 @@ """ in d res = d['f']() assert res == (3, 2) + + def test_space_bug(self): + d = {} + exec "x=5 " in d + assert d['x'] == 5 From lac at codespeak.net Fri Aug 26 13:57:36 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Fri, 26 Aug 2005 13:57:36 +0200 (CEST) Subject: [pypy-svn] r16612 - pypy/dist/pypy/tool/test Message-ID: <20050826115736.DE16D27B52@code1.codespeak.net> Author: lac Date: Fri Aug 26 13:57:35 2005 New Revision: 16612 Added: pypy/dist/pypy/tool/test/fordocstrings1 Modified: pypy/dist/pypy/tool/test/test_getdocstrings.py Log: Ooops, forgot to check in fordocstrings1. Thanks Samuele. Added: pypy/dist/pypy/tool/test/fordocstrings1 ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/test/fordocstrings1 Fri Aug 26 13:57:35 2005 @@ -0,0 +1,7 @@ +from pypy.objspace.std.stdtypedef import * + + +# ____________________________________________________________ + +basestring_typedef = StdTypeDef("basestring", + ) Modified: pypy/dist/pypy/tool/test/test_getdocstrings.py ============================================================================== --- pypy/dist/pypy/tool/test/test_getdocstrings.py (original) +++ pypy/dist/pypy/tool/test/test_getdocstrings.py Fri Aug 26 13:57:35 2005 @@ -44,9 +44,7 @@ re.DOTALL ) - print s tdsearch = typedef.search(s).group('typeassign') - assert tdsearch From hpk at codespeak.net Fri Aug 26 14:18:02 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 14:18:02 +0200 (CEST) Subject: [pypy-svn] r16615 - in pypy/dist/pypy: interpreter tool Message-ID: <20050826121802.4280527B5D@code1.codespeak.net> Author: hpk Date: Fri Aug 26 14:18:01 2005 New Revision: 16615 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/tool/option.py Log: (hpk,ludal) only offer 'pypy' and 'cpython' as parser module options. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Fri Aug 26 14:18:01 2005 @@ -115,7 +115,7 @@ def __init__(self, usemodules=(), nofaking=False, uselibfile=False, - parser="recparser", + parser="pypy", compiler="pyparse", translating=False, geninterp=True, @@ -190,11 +190,9 @@ # that differs from the app-visible name (because you # can specify implementation variants) builtinmodule_list = [(x, None) for x in modules] - if self.options.parser == "recparser": + if self.options.parser == "pypy": builtinmodule_list.append(('parser', 'recparser')) builtinmodule_list.append(('symbol', None)) - elif self.options.parser == "parser": - builtinmodule_list.append(('parser', None)) self._builtinmodule_list = builtinmodule_list return self._builtinmodule_list Modified: pypy/dist/pypy/tool/option.py ============================================================================== --- pypy/dist/pypy/tool/option.py (original) +++ pypy/dist/pypy/tool/option.py Fri Aug 26 14:18:01 2005 @@ -11,7 +11,7 @@ oldstyle = 0 uselibfile = 0 nofaking = 0 - parser = "recparser" # "cpython" / "recparser" / "parser" + parser = "pypy" # "cpython" / "pypy" compiler = "pyparse" # "cpython" # "pyparse" pypy parser, cpython's compiler and transformer package # "pyparseapp" same, running the compiler at app-level @@ -60,7 +60,7 @@ options.append(make_option( '--parser', action="store",type="string", dest="parser", help="select the parser module to use", - metavar="[recparser|cpython|parser]")) + metavar="[pypy|cpython]")) ## for this to work the option module need to be loaded before the grammar! ## options.append(make_option( ## '--version', action="store",type="string", dest="version", From ac at codespeak.net Fri Aug 26 14:23:42 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 26 Aug 2005 14:23:42 +0200 (CEST) Subject: [pypy-svn] r16616 - pypy/dist/pypy/lib/test2 Message-ID: <20050826122342.3B17627B5D@code1.codespeak.net> Author: ac Date: Fri Aug 26 14:23:37 2005 New Revision: 16616 Modified: pypy/dist/pypy/lib/test2/test_file_extra.py Log: Apply patch from Ben Young. Modified: pypy/dist/pypy/lib/test2/test_file_extra.py ============================================================================== --- pypy/dist/pypy/lib/test2/test_file_extra.py (original) +++ pypy/dist/pypy/lib/test2/test_file_extra.py Fri Aug 26 14:23:37 2005 @@ -27,7 +27,7 @@ def test_repr(self): r = repr(self.file) assert r.find('open file') >= 0 - assert r.find(self.file.name) >= 0 + assert r.find(repr(self.file.name)) >= 0 assert r.find(self.file.mode) >= 0 class TestFdFile(TestFile): From ac at codespeak.net Fri Aug 26 14:29:29 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 26 Aug 2005 14:29:29 +0200 (CEST) Subject: [pypy-svn] r16617 - pypy/dist/pypy/module/unicodedata/test Message-ID: <20050826122929.04D6327B69@code1.codespeak.net> Author: ac Date: Fri Aug 26 14:29:28 2005 New Revision: 16617 Modified: pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py Log: Skip test if run by a "narrow" python build. Modified: pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py ============================================================================== --- pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py (original) +++ pypy/dist/pypy/module/unicodedata/test/test_unicodedata.py Fri Aug 26 14:29:28 2005 @@ -41,6 +41,9 @@ raises(ValueError, unicodedata.name, unichr(0xD7A3 + 1)) def test_cjk(self): + import sys + if sys.maxunicode < 0x10ffff: + skip("requires a 'wide' python build.") import unicodedata for first, last in ((0x3400, 0x4DB5), (0x4E00, 0x9FA5), # 9FBB in Unicode 4.1 From tismer at codespeak.net Fri Aug 26 14:31:12 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 14:31:12 +0200 (CEST) Subject: [pypy-svn] r16618 - pypy/dist/pypy/module/math Message-ID: <20050826123112.BE5DE27B69@code1.codespeak.net> Author: tismer Date: Fri Aug 26 14:31:11 2005 New Revision: 16618 Modified: pypy/dist/pypy/module/math/__init__.py Log: removed outdated comment Modified: pypy/dist/pypy/module/math/__init__.py ============================================================================== --- pypy/dist/pypy/module/math/__init__.py (original) +++ pypy/dist/pypy/module/math/__init__.py Fri Aug 26 14:31:11 2005 @@ -6,9 +6,6 @@ appleveldefs = { } - # XXX the reason for the commented out names - # is that we need to add support to - # extfunctable/translation interpleveldefs = { 'e' : 'interp_math.get(space).w_e', 'pi' : 'interp_math.get(space).w_pi', From arigo at codespeak.net Fri Aug 26 14:33:09 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 14:33:09 +0200 (CEST) Subject: [pypy-svn] r16619 - in pypy/dist/pypy/interpreter: pyparser test Message-ID: <20050826123309.54C9B27B69@code1.codespeak.net> Author: arigo Date: Fri Aug 26 14:33:07 2005 New Revision: 16619 Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py pypy/dist/pypy/interpreter/test/test_compiler.py Log: Complain in the tokenizer when parenthesis nesting level become negative. Helps with the following interactive sessions: >>>> ) .... .... .... .... ( Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Fri Aug 26 14:33:07 2005 @@ -273,6 +273,9 @@ parenlev = parenlev + 1 elif initial in ')]}': parenlev = parenlev - 1 + if parenlev < 0: + raise TokenError("unmatched '%s'" % initial, line, + (lnum-1, 0), token_list) if token in pytoken.tok_punct: tok = Token(pytoken.tok_punct[token]) else: Modified: pypy/dist/pypy/interpreter/test/test_compiler.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_compiler.py (original) +++ pypy/dist/pypy/interpreter/test/test_compiler.py Fri Aug 26 14:33:07 2005 @@ -47,6 +47,8 @@ space = self.space space.raises_w(space.w_SyntaxError, self.compiler.compile_command, 'if 1:\n x x', '?', mode, 0) + space.raises_w(space.w_SyntaxError, self.compiler.compile_command, + ')', '?', mode, 0) def test_getcodeflags(self): code = self.compiler.compile('from __future__ import division\n', From arigo at codespeak.net Fri Aug 26 14:46:41 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 14:46:41 +0200 (CEST) Subject: [pypy-svn] r16621 - in pypy/dist/pypy/module/time: . test Message-ID: <20050826124641.2B51F27B69@code1.codespeak.net> Author: arigo Date: Fri Aug 26 14:46:39 2005 New Revision: 16621 Modified: pypy/dist/pypy/module/time/__init__.py pypy/dist/pypy/module/time/interp_time.py pypy/dist/pypy/module/time/test/test_time.py Log: Missing time.sleep() in our 'time' mixed module. Modified: pypy/dist/pypy/module/time/__init__.py ============================================================================== --- pypy/dist/pypy/module/time/__init__.py (original) +++ pypy/dist/pypy/module/time/__init__.py Fri Aug 26 14:46:39 2005 @@ -12,5 +12,6 @@ interpleveldefs = { 'clock' : 'interp_time.clock', 'time' : 'interp_time.time_', + 'sleep' : 'interp_time.sleep', } Modified: pypy/dist/pypy/module/time/interp_time.py ============================================================================== --- pypy/dist/pypy/module/time/interp_time.py (original) +++ pypy/dist/pypy/module/time/interp_time.py Fri Aug 26 14:46:39 2005 @@ -5,3 +5,7 @@ def time_(space): return space.wrap(time.time()) + +def sleep(seconds): + time.sleep(seconds) +sleep.unwrap_spec = [float] Modified: pypy/dist/pypy/module/time/test/test_time.py ============================================================================== --- pypy/dist/pypy/module/time/test/test_time.py (original) +++ pypy/dist/pypy/module/time/test/test_time.py Fri Aug 26 14:46:39 2005 @@ -18,3 +18,9 @@ t2 = time.time() assert t0 <= space.unwrap(w_t1) <= t2 + def test_sleep(self): + w_sleep = space.appexec([], """(): import time; return time.sleep""") + t0 = time.time() + space.call_function(w_sleep, space.wrap(0.3)) + t1 = time.time() + assert t1-t0 > 0.25 From hpk at codespeak.net Fri Aug 26 14:49:07 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 14:49:07 +0200 (CEST) Subject: [pypy-svn] r16622 - in pypy/dist/pypy: doc interpreter objspace/std tool translator/goal Message-ID: <20050826124907.530AE27B69@code1.codespeak.net> Author: hpk Date: Fri Aug 26 14:49:06 2005 New Revision: 16622 Added: pypy/dist/pypy/doc/README.compiling Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/tool/option.py pypy/dist/pypy/translator/goal/targetpypymain.py pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: (hpk,ludal) refactor the compiler option to make it more easily understandable for pypy developers. doc/README.compiling is to contain some more information about the compiling approaches and how they relate to translation and to the various copies of compilers in our tree. Added: pypy/dist/pypy/doc/README.compiling ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/README.compiling Fri Aug 26 14:49:06 2005 @@ -0,0 +1,8 @@ + +Compiling approaches +-------------------------- + +stable: use interpreter/stablecompiler at interp-level +_stable: use lib/_stablecompiler at applevel. +ast: use in-development translatable interplevel compiling. +cpython: use cpython builtin c-level compiler. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Fri Aug 26 14:49:06 2005 @@ -116,7 +116,7 @@ nofaking=False, uselibfile=False, parser="pypy", - compiler="pyparse", + compiler="stable", translating=False, geninterp=True, **kw @@ -263,12 +263,12 @@ try: return self.default_compiler except AttributeError: - if (self.options.compiler == 'pyparse' or - self.options.compiler == 'pyparseapp'): + if (self.options.compiler == 'stable' or + self.options.compiler == '_stable'): compiler = PythonCompiler(self) elif self.options.compiler == 'cpython': compiler = CPythonCompiler(self) - elif self.options.compiler == 'astparser': + elif self.options.compiler == 'ast': compiler = PythonAstCompiler(self) else: raise ValueError('unknown --compiler option value: %r' % ( Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Fri Aug 26 14:49:06 2005 @@ -99,7 +99,7 @@ self.inituselibfile() # XXX hack!: patch the compiler after initialization is complete - if self.options.compiler == 'pyparseapp': + if self.options.compiler == '_stable': from pypy.interpreter.pycompiler import PythonCompilerApp self.default_compiler = PythonCompilerApp(self) self.getexecutioncontext().compiler = self.default_compiler Modified: pypy/dist/pypy/tool/option.py ============================================================================== --- pypy/dist/pypy/tool/option.py (original) +++ pypy/dist/pypy/tool/option.py Fri Aug 26 14:49:06 2005 @@ -12,11 +12,11 @@ uselibfile = 0 nofaking = 0 parser = "pypy" # "cpython" / "pypy" - compiler = "pyparse" # "cpython" - # "pyparse" pypy parser, cpython's compiler and transformer package - # "pyparseapp" same, running the compiler at app-level - # "astparser" pypy parser with ast builder using cpython's compiler - # "pycomp" pypy parser and compiler (TBD) + compiler = "stable" + # "stable" uses interpreter/pyparser & interpreter/stablecompiler + # "_stable" uses intepreter/pyparser & lib/_stablecompiler + # "ast" uses interpreter/pyparser & interpreter/astcompiler.py + # "cpython" uses cpython parser and cpython c-level compiler usemodules = [] version = "2.4" # "native" / "2.3" / "2.4" @@ -55,8 +55,8 @@ help="use web browser for traceback info")) options.append(make_option( '--compiler', action="store", type="string", dest="compiler", - help="select the compiler approach to use internally", - metavar="[pyparse|astparser|cpython|pyparseapp]")) + help="""select compiling approach. see pypy/doc/README.compiling""", + metavar="[stable|_stable|ast|cpython]")) options.append(make_option( '--parser', action="store",type="string", dest="parser", help="select the parser module to use", Modified: pypy/dist/pypy/translator/goal/targetpypymain.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypymain.py Fri Aug 26 14:49:06 2005 @@ -54,7 +54,7 @@ # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None space = StdObjSpace(nofaking=True, - compiler="pyparseapp", + compiler="_stable", # lib/_stablecompiler translating=True, #usemodules=['marshal', '_sre'], geninterp=geninterp) Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Fri Aug 26 14:49:06 2005 @@ -49,7 +49,7 @@ # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None space = StdObjSpace(nofaking=True, - compiler="pyparseapp", + compiler="_stable", # lib/_stablecompiler translating=True, usemodules=['thread'], geninterp=geninterp) From pedronis at codespeak.net Fri Aug 26 14:49:14 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 14:49:14 +0200 (CEST) Subject: [pypy-svn] r16623 - pypy/extradoc/sprintinfo Message-ID: <20050826124914.3040C27B71@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 14:49:12 2005 New Revision: 16623 Modified: pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt Log: updated, added status info in parallel to filing new issues for the not so far addressed stuff Modified: pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt ============================================================================== --- pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt (original) +++ pypy/extradoc/sprintinfo/Hildes_to_Heidel.txt Fri Aug 26 14:49:12 2005 @@ -7,51 +7,51 @@ the following issues are meant to be 0.7 issues. -- translate_pypy and the translator class need some cleanup +- FILED translate_pypy and -- initialization of the object space is still messy +- FILED the translator class need some cleanup -- move bits around in the annotator to make different uses - more pluggable +- FILED initialization of the object space is still messy -- reorganizing some wrongly named things +- move bits around in the annotator to make different uses + more pluggable ? -- erasing useless files +- reorganizing some wrongly named things ? -- cleanup of import dependencies +- FILED erasing useless files -- preparing the next release +- FILED cleanup of import dependencies -- look into XXX issues +- ONGOING preparing the next release filed as issues ----------------- -- rtyper problem: exceptions are no longer always at the end of a code +- DONE rtyper problem: exceptions are no longer always at the end of a code block because of the lowlevel rewriting -- translation problem: frozen ids used as hashes are broken +- DONE translation problem: frozen ids used as hashes are broken in the post-translation program -- better support of math and float exceptions +- DONE better support of math and float exceptions -- documentation about external function calls and implementing +- FILED documentation about external function calls and implementing builtin modules -- prefixing all the C macros and names with pypy - -- support producing a windows binary, choose a suitable compiler +- DONE prefixing all the C macros and names with pypy +- DONE support producing a windows binary, choose a suitable compiler -- related to the previous: documenting how interplevel marshal +- OPEN related to the previous: documenting how interplevel marshal is plugged into the system -- support for tests from external users and different platforms +- FILED support for tests from external users and different platforms other issues --------------------- +FILED storing bound method on instances confuses the annotator (we can probably live with this limitation right now, I'm not sure but it may require a large refactoring to support this) @@ -76,7 +76,7 @@ -additional wild ideas +Additional wild ideas --------------------- - thinking of an RPython flowgraph interpreter as an executable? From arigo at codespeak.net Fri Aug 26 14:52:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 14:52:12 +0200 (CEST) Subject: [pypy-svn] r16624 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050826125212.9901127B69@code1.codespeak.net> Author: arigo Date: Fri Aug 26 14:52:09 2005 New Revision: 16624 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py Log: Fixed a test for the previous change in the tokenizer. Modified: pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_pytokenizer.py Fri Aug 26 14:52:09 2005 @@ -26,7 +26,7 @@ '+=', '>>=', '=', '&=', '/=', '-=', ',', '^', '>>', '&', '+', '*', '-', '/', '.', '**', '%', '<<', '//', '|', ')', '(', ';', ':', - # '@', # XXX This one is skipped for now (?!) + '@', '[', ']', '`', '{', '}', ] @@ -71,10 +71,16 @@ def test_punct(): """make sure each punctuation is correctly parsed""" for pstr in PUNCTS: + if pstr == ')': prefix = '(' + elif pstr == ']': prefix = '[' + elif pstr == '}': prefix = '{' + else: prefix = '' try: - tokens = parse_source(pstr) + tokens = parse_source(prefix+pstr) except TokenError, error: tokens = [tok for tok, _, _, _ in error.token_stack] + if prefix: + tokens.pop(0) assert tokens[0].codename == tok_punct[pstr] From rxe at codespeak.net Fri Aug 26 15:02:33 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 26 Aug 2005 15:02:33 +0200 (CEST) Subject: [pypy-svn] r16625 - pypy/dist/pypy/translator/llvm2 Message-ID: <20050826130233.7C99C27B69@code1.codespeak.net> Author: rxe Date: Fri Aug 26 15:02:32 2005 New Revision: 16625 Modified: pypy/dist/pypy/translator/llvm2/genllvm.py Log: Test whether we want to run llvm tests was done later than what we wanted. Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Fri Aug 26 15:02:32 2005 @@ -375,10 +375,6 @@ optimize=True, exe_name=None): - if not llvm_is_on_path(): - # XXX not good to call py.test.skip here - py.test.skip("llvm not found") - if standalone: return build_llvm_module.make_module_from_llvm(filename, optimize=optimize, @@ -396,6 +392,10 @@ codewriter.append("declare int %printf(sbyte*, ...)") def genllvm(translator, log_source=False, **kwds): + if not llvm_is_on_path(): + # XXX not good to call py.test.skip here + py.test.skip("llvm not found") + gen = GenLLVM(translator) filename = gen.gen_llvm_source() if log_source: From arigo at codespeak.net Fri Aug 26 15:04:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 15:04:27 +0200 (CEST) Subject: [pypy-svn] r16626 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20050826130427.1BC1727B69@code1.codespeak.net> Author: arigo Date: Fri Aug 26 15:04:25 2005 New Revision: 16626 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Log: The global name 'raises' conflicts with the conftest's magic, which inserts a 'raises' into the module too. Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Fri Aug 26 15:04:25 2005 @@ -294,7 +294,7 @@ 'global a,b,c', ] -raises = [ +raises_ = [ # NB. 'raises' creates a name conflict with py.test magic 'raise', 'raise ValueError', 'raise ValueError("error")', @@ -491,7 +491,7 @@ execs, prints, globs, - raises, + raises_, ] EXEC_INPUTS = [ Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Fri Aug 26 15:04:25 2005 @@ -7,7 +7,7 @@ from test_astbuilder import expressions, comparisons, funccalls, backtrackings,\ listmakers, genexps, dictmakers, multiexpr, attraccess, slices, imports,\ - asserts, execs, prints, globs, raises, imports_newstyle, augassigns + asserts, execs, prints, globs, raises_, imports_newstyle, augassigns from test_astbuilder import FakeSpace @@ -27,7 +27,7 @@ execs, prints, globs, - raises, + raises_, ] import sys From ludal at codespeak.net Fri Aug 26 15:05:46 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 15:05:46 +0200 (CEST) Subject: [pypy-svn] r16627 - in pypy/dist/lib-python: . modified-2.4.1/test Message-ID: <20050826130546.0098927B6C@code1.codespeak.net> Author: ludal Date: Fri Aug 26 15:05:44 2005 New Revision: 16627 Added: pypy/dist/lib-python/modified-2.4.1/test/test_genexps.py - copied, changed from r16563, pypy/dist/lib-python/2.4.1/test/test_genexps.py Modified: pypy/dist/lib-python/conftest.py Log: make test compiler non-core make test_genexps a bit faster Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Aug 26 15:05:44 2005 @@ -440,7 +440,7 @@ RegrTest('test_commands.py', enabled=True), RegrTest('test_compare.py', enabled=True, oldstyle=True, core=True), RegrTest('test_compile.py', enabled=True, core=True), - RegrTest('test_compiler.py', enabled=True, core=True), + RegrTest('test_compiler.py', enabled=True, core=False), # this test tests the compiler package from stdlib RegrTest('test_complex.py', enabled=True, core=True), RegrTest('test_contains.py', enabled=True, dumbtest=1, core=True), From ericvrp at codespeak.net Fri Aug 26 15:07:37 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 26 Aug 2005 15:07:37 +0200 (CEST) Subject: [pypy-svn] r16629 - in pypy/dist/pypy/translator/llvm2: . demo module Message-ID: <20050826130737.F267C27B6C@code1.codespeak.net> Author: ericvrp Date: Fri Aug 26 15:07:35 2005 New Revision: 16629 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/demo/bpnn.py pypy/dist/pypy/translator/llvm2/demo/richards.py pypy/dist/pypy/translator/llvm2/extfuncnode.py pypy/dist/pypy/translator/llvm2/funcnode.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/genexterns.c pypy/dist/pypy/translator/llvm2/module/support.py pypy/dist/pypy/translator/llvm2/opwriter.py Log: intermediate checking while prefixing functions with pypy_ Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Fri Aug 26 15:07:35 2005 @@ -35,6 +35,7 @@ ])) def compile_module(module, source_files, object_files, library_files): + print 'QQQQQQQQQQQ compile_module' open("%s_setup.py" % module, "w").write(str(py.code.Source( ''' from distutils.core import setup @@ -51,11 +52,18 @@ cmdexec(cmd) def make_module_from_llvm(llvmfile, pyxfile=None, optimize=True, exe_name=None): + print 'QQQQQQQQQQQ make_module_from_llvm' + print 'QQQQQQQ aaa make_module_from_llvm' include_dir = py.magic.autopath().dirpath() + print 'QQQQQQQ AAA make_module_from_llvm' dirpath = llvmfile.dirpath() + print 'QQQQQQQ BBB make_module_from_llvm' lastdir = path.local() + print 'QQQQQQQ CCC make_module_from_llvm' os.chdir(str(dirpath)) + print 'QQQQQQQ DDD make_module_from_llvm' b = llvmfile.purebasename + print 'QQQQQQQ EEE make_module_from_llvm' if pyxfile: modname = pyxfile.purebasename source_files = [ "%s.c" % modname ] @@ -84,6 +92,7 @@ cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, OPTIMIZATION_SWITCHES, b)] + print 'QQQQQQQ 111 make_module_from_llvm' if False and sys.maxint == 2147483647: #32 bit platform cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) @@ -94,33 +103,45 @@ #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)) if exe_name: - cmds.append("gcc -g %s.c -c -O2 -fomit-frame-pointer" % (b,)) - cmds.append("gcc -g %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) + cmds.append("gcc %s.c -c -O2 -fomit-frame-pointer" % (b,)) + cmds.append("gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) source_files.append("%s.c" % b) try: + print 'QQQQQQQ 222 make_module_from_llvm' if pyxfile: log.build("modname", modname) c = stdoutcapture.Capture(mixed_out_err = True) log.build("working in", path.local()) + print 'QQQ X 111 make_module_from_llvm' try: + print 'QQQ X 222 make_module_from_llvm' try: + print 'QQQ X 333 make_module_from_llvm' for cmd in cmds: #log.build(cmd) + print 'QQQQQQQQQQQ cmd', cmd cmdexec(cmd) if pyxfile: + print 'QQQ aaa ', cmd make_c_from_pyxfile(pyxfile) + print 'QQQ bbb ', cmd compile_module(modname, source_files, object_files, library_files) + print 'QQQ ccc ', cmd + print 'QQQ ddd ', cmd finally: - foutput, foutput = c.done() + print 'QQQ eee ', cmd + foutput, ferror = c.done() except: - data = foutput.read() + print 'QQQ fff ', cmd + data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() if pyxfile: fdump = open("%s.errors" % modname, "w") fdump.write(data) fdump.close() log.build(data) raise + print 'QQQQQQQ bbb make_module_from_llvm' # XXX do we need to do some check on fout/ferr? # XXX not a nice way to import a module if pyxfile: @@ -132,7 +153,10 @@ sys.path.pop(0) finally: os.chdir(str(lastdir)) + print 'QQQQQQQ ccc make_module_from_llvm' if pyxfile: + print 'QQQQQQQ ddd make_module_from_llvm' return testmodule if exe_name: + print 'QQQQQQQ eee make_module_from_llvm' return exe_name Modified: pypy/dist/pypy/translator/llvm2/demo/bpnn.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/bpnn.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/bpnn.py Fri Aug 26 15:07:35 2005 @@ -233,7 +233,7 @@ print "compared to", t2 print "a speed-up of", t2/t1 -def main(): +def main_noargs(): T = time.time() os.write(1, 'Running...\n') @@ -246,4 +246,4 @@ if __name__ == "__main__": from pypy.translator.llvm2.demo.run import run - run(main, "bpnn") + run(main_noargs, "bpnn") Modified: pypy/dist/pypy/translator/llvm2/demo/richards.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/demo/richards.py (original) +++ pypy/dist/pypy/translator/llvm2/demo/richards.py Fri Aug 26 15:07:35 2005 @@ -408,7 +408,7 @@ endTime = time.time() return result, startTime, endTime -def main(): +def main_noargs(): os.write(1, "Richards benchmark starting... \n") result, startTime, endTime = entry_point() if not result: @@ -423,4 +423,4 @@ if __name__ == "__main__": import autopath from pypy.translator.llvm2.demo.run import run - run(main, "richards") + run(main_noargs, "richards") Modified: pypy/dist/pypy/translator/llvm2/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/extfuncnode.py (original) +++ pypy/dist/pypy/translator/llvm2/extfuncnode.py Fri Aug 26 15:07:35 2005 @@ -9,7 +9,7 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = "%" + value._callable.__name__ + self.ref = "%pypy_" + value._callable.__name__ def getdecl(self): T = self.value._TYPE Modified: pypy/dist/pypy/translator/llvm2/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm2/funcnode.py Fri Aug 26 15:07:35 2005 @@ -32,7 +32,7 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = self.make_ref('%', value.graph.name) + self.ref = self.make_ref('%', 'pypy_' + value.graph.name) self.graph = value.graph remove_same_as(self.graph) remove_double_links(self.db._translator, self.graph) Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Fri Aug 26 15:07:35 2005 @@ -332,11 +332,15 @@ codewriter.append(" ret int %result") codewriter.append("}") codewriter.newline() + # XXX we need to create our own main() that calls the actual entry_point function entryfunc_name = t[1].split('(')[0] - if entryfunc_name != 'main' and entryfunc_name == 'entry_point': #XXX just to get on with translate_pypy + if entryfunc_name == 'pypy_entry_point': #XXX just to get on with translate_pypy extfuncnode.ExternalFuncNode.used_external_functions['%main'] = True + elif entryfunc_name == 'pypy_main_noargs': #XXX just to get on with bpnn & richards + extfuncnode.ExternalFuncNode.used_external_functions['%main_noargs'] = True + for f in "prepare_and_raise_OverflowError prepare_and_raise_ValueError "\ "prepare_and_raise_ZeroDivisionError prepare_and_raise_IOError "\ "RPyString_FromString RPyString_AsString RPyString_Size".split(): Modified: pypy/dist/pypy/translator/llvm2/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm2/module/genexterns.c Fri Aug 26 15:07:35 2005 @@ -13,9 +13,9 @@ struct RPyString; struct RPySTAT_RESULT; -struct RPyFREXP_RESULT *ll_frexp_result__Float_Signed(double, int); -struct RPyMODF_RESULT *ll_modf_result__Float_Float(double, double); -struct RPySTAT_RESULT *ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(int, int, int, int, int, +struct RPyFREXP_RESULT *pypy_ll_frexp_result__Float_Signed(double, int); +struct RPyMODF_RESULT *pypy_ll_modf_result__Float_Float(double, double); +struct RPySTAT_RESULT *pypy_ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(int, int, int, int, int, int, int, int, int, int); char *RPyString_AsString(struct RPyString*); int RPyString_Size(struct RPyString*); @@ -24,11 +24,11 @@ void prepare_and_raise_OverflowError(char *); void prepare_and_raise_ValueError(char *); void prepare_and_raise_IOError(char *); -void ll_raise_OSError__Signed(int error); +void pypy_ll_raise_OSError__Signed(int error); -#define RPYTHON_RAISE_OSERROR(error) ll_raise_OSError__Signed(error) +#define RPYTHON_RAISE_OSERROR(error) pypy_ll_raise_OSError__Signed(error) -int ll_math_is_error(double x) { +int pypy_ll_math_is_error(double x) { if (errno == ERANGE) { if (!x) return 0; @@ -43,12 +43,12 @@ #define LL_MATH_CHECK_ERROR(x, errret) do { \ LL_MATH_SET_ERANGE_IF_MATH_ERROR(x); \ - if (errno && ll_math_is_error(x)) \ + if (errno && pypy_ll_math_is_error(x)) \ return errret; \ } while(0) -double ll_math_pow(double x, double y) { +double pypy_ll_math_pow(double x, double y) { double r; LL_MATH_ERROR_RESET; r = pow(x, y); @@ -56,7 +56,7 @@ return r; } -double ll_math_atan2(double x, double y) { +double pypy_ll_math_atan2(double x, double y) { double r; LL_MATH_ERROR_RESET; r = atan2(x, y); @@ -64,7 +64,7 @@ return r; } -double ll_math_fmod(double x, double y) { +double pypy_ll_math_fmod(double x, double y) { double r; LL_MATH_ERROR_RESET; r = fmod(x, y); @@ -72,7 +72,7 @@ return r; } -double ll_math_ldexp(double x, long y) { +double pypy_ll_math_ldexp(double x, long y) { double r; LL_MATH_ERROR_RESET; r = ldexp(x, (int) y); @@ -80,7 +80,7 @@ return r; } -double ll_math_hypot(double x, double y) { +double pypy_ll_math_hypot(double x, double y) { double r; LL_MATH_ERROR_RESET; r = hypot(x, y); @@ -88,17 +88,17 @@ return r; } -struct RPyMODF_RESULT* ll_math_modf(double x) { +struct RPyMODF_RESULT* pypy_ll_math_modf(double x) { double intpart, fracpart; LL_MATH_ERROR_RESET; fracpart = modf(x, &intpart); LL_MATH_CHECK_ERROR(fracpart, NULL); - return ll_modf_result__Float_Float(fracpart, intpart); + return pypy_ll_modf_result__Float_Float(fracpart, intpart); } /* simple math function */ -double ll_math_acos(double x) { +double pypy_ll_math_acos(double x) { double r; LL_MATH_ERROR_RESET; r = acos(x); @@ -106,7 +106,7 @@ return r; } -double ll_math_asin(double x) { +double pypy_ll_math_asin(double x) { double r; LL_MATH_ERROR_RESET; r = asin(x); @@ -114,7 +114,7 @@ return r; } -double ll_math_atan(double x) { +double pypy_ll_math_atan(double x) { double r; LL_MATH_ERROR_RESET; r = atan(x); @@ -122,7 +122,7 @@ return r; } -double ll_math_ceil(double x) { +double pypy_ll_math_ceil(double x) { double r; LL_MATH_ERROR_RESET; r = ceil(x); @@ -130,7 +130,7 @@ return r; } -double ll_math_cos(double x) { +double pypy_ll_math_cos(double x) { double r; LL_MATH_ERROR_RESET; r = cos(x); @@ -138,7 +138,7 @@ return r; } -double ll_math_cosh(double x) { +double pypy_ll_math_cosh(double x) { double r; LL_MATH_ERROR_RESET; r = cosh(x); @@ -146,7 +146,7 @@ return r; } -double ll_math_exp(double x) { +double pypy_ll_math_exp(double x) { double r; LL_MATH_ERROR_RESET; r = exp(x); @@ -154,7 +154,7 @@ return r; } -double ll_math_fabs(double x) { +double pypy_ll_math_fabs(double x) { double r; LL_MATH_ERROR_RESET; r = fabs(x); @@ -162,7 +162,7 @@ return r; } -double ll_math_floor(double x) { +double pypy_ll_math_floor(double x) { double r; LL_MATH_ERROR_RESET; r = floor(x); @@ -170,7 +170,7 @@ return r; } -double ll_math_log(double x) { +double pypy_ll_math_log(double x) { double r; LL_MATH_ERROR_RESET; r = log(x); @@ -178,7 +178,7 @@ return r; } -double ll_math_log10(double x) { +double pypy_ll_math_log10(double x) { double r; LL_MATH_ERROR_RESET; r = log10(x); @@ -186,7 +186,7 @@ return r; } -double ll_math_sin(double x) { +double pypy_ll_math_sin(double x) { double r; LL_MATH_ERROR_RESET; r = sin(x); @@ -194,7 +194,7 @@ return r; } -double ll_math_sinh(double x) { +double pypy_ll_math_sinh(double x) { double r; LL_MATH_ERROR_RESET; r = sinh(x); @@ -202,7 +202,7 @@ return r; } -double ll_math_sqrt(double x) { +double pypy_ll_math_sqrt(double x) { double r; LL_MATH_ERROR_RESET; r = sqrt(x); @@ -210,7 +210,7 @@ return r; } -double ll_math_tan(double x) { +double pypy_ll_math_tan(double x) { double r; LL_MATH_ERROR_RESET; r = tan(x); @@ -218,7 +218,7 @@ return r; } -double ll_math_tanh(double x) { +double pypy_ll_math_tanh(double x) { double r; LL_MATH_ERROR_RESET; r = tanh(x); @@ -226,13 +226,13 @@ return r; } -struct RPyFREXP_RESULT* ll_math_frexp(double x) { +struct RPyFREXP_RESULT* pypy_ll_math_frexp(double x) { int expo; double m; LL_MATH_ERROR_RESET; m= frexp(x, &expo); LL_MATH_CHECK_ERROR(m, NULL); - return ll_frexp_result__Float_Signed(m, expo); + return pypy_ll_frexp_result__Float_Signed(m, expo); } /************************************************************/ @@ -251,7 +251,7 @@ XXX Win64 does not yet, but might when the platform matures. */ #include -double ll_time_clock(void) +double pypy_ll_time_clock(void) { static LARGE_INTEGER ctrStart; static double divisor = 0.0; @@ -283,14 +283,14 @@ #endif #endif -double ll_time_clock(void) +double pypy_ll_time_clock(void) { return ((double)clock()) / CLOCKS_PER_SEC; } #endif /* MS_WINDOWS */ -void ll_time_sleep(double secs) +void pypy_ll_time_sleep(double secs) { #if defined(MS_WINDOWS) double millisecs = secs * 1000.0; @@ -343,7 +343,7 @@ #endif /* MS_WINDOWS */ #endif /* HAVE_FTIME */ -double ll_floattime(void) +double pypy_ll_floattime(void) { /* There are three ways to get the time: (1) gettimeofday() -- resolution in microseconds @@ -378,13 +378,13 @@ } } -double ll_time_time(void) /* xxx had support for better resolutions */ +double pypy_ll_time_time(void) /* xxx had support for better resolutions */ { - return ll_floattime(); + return pypy_ll_floattime(); } -double ll_strtod_parts_to_float(struct RPyString *sign, +double pypy_ll_strtod_parts_to_float(struct RPyString *sign, struct RPyString *beforept, struct RPyString *afterpt, struct RPyString *exponent) @@ -445,7 +445,7 @@ } -struct RPyString *ll_strtod_formatd(struct RPyString *fmt, double x) { +struct RPyString *pypy_ll_strtod_formatd(struct RPyString *fmt, double x) { char buffer[120]; /* this should be enough, from PyString_Format code */ int buflen = 120; int res; @@ -512,9 +512,9 @@ /* The functions below are mapped to functions from pypy.rpython.module.* by the pypy.translator.c.extfunc.EXTERNALS dictionary. They should correspond to the functions with the suggested_primitive - flag set, and NOT necessarily directly to the ll_os_*() functions. - See for example ll_read_into(), which is called by ll_os_read(). - The latter would be messy to write here, but ll_read_into() is quite easy. + flag set, and NOT necessarily directly to the pypy_ll_os_*() functions. + See for example pypy_ll_read_into(), which is called by pypy_ll_os_read(). + The latter would be messy to write here, but pypy_ll_read_into() is quite easy. */ @@ -531,7 +531,7 @@ #endif -int ll_os_open(struct RPyString *filename, int flag, int mode) +int pypy_ll_os_open(struct RPyString *filename, int flag, int mode) { /* XXX unicode_file_names */ char buf[PATH_MAX]; @@ -550,7 +550,7 @@ } } -long ll_read_into(int fd, struct RPyString *buffer) +long pypy_ll_read_into(int fd, struct RPyString *buffer) { long n = read(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) @@ -558,7 +558,7 @@ return n; } -long ll_os_write(int fd, struct RPyString *buffer) +long pypy_ll_os_write(int fd, struct RPyString *buffer) { long n = write(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) @@ -566,13 +566,13 @@ return n; } -void ll_os_close(int fd) +void pypy_ll_os_close(int fd) { if (close(fd) < 0) RPYTHON_RAISE_OSERROR(errno); } -int ll_os_dup(int fd) +int pypy_ll_os_dup(int fd) { fd = dup(fd); if (fd < 0) @@ -580,7 +580,7 @@ return fd; } -struct RPyString *ll_os_getcwd(void) +struct RPyString *pypy_ll_os_getcwd(void) { char buf[PATH_MAX]; char *res; @@ -606,12 +606,12 @@ res9 = (long)st.st_ctime; /*XXX ignoring quite a lot of things for time here */ /*XXX ignoring BLOCK info here*/ - return ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(res0, res1, res2, res3, res4, + return pypy_ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(res0, res1, res2, res3, res4, res5, res6, res7, res8, res9); } -struct RPySTAT_RESULT* ll_os_stat(struct RPyString * fname) { +struct RPySTAT_RESULT* pypy_ll_os_stat(struct RPyString * fname) { STRUCT_STAT st; int error = STAT(RPyString_AsString(fname), &st); if (error != 0) { @@ -621,7 +621,7 @@ return _stat_construct_result_helper(st); } -struct RPySTAT_RESULT* ll_os_fstat(long fd) { +struct RPySTAT_RESULT* pypy_ll_os_fstat(long fd) { STRUCT_STAT st; int error = FSTAT(fd, &st); if (error != 0) { @@ -631,7 +631,7 @@ return _stat_construct_result_helper(st); } -long ll_os_lseek(long fd, long pos, long how) { +long pypy_ll_os_lseek(long fd, long pos, long how) { #if defined(MS_WIN64) || defined(MS_WINDOWS) PY_LONG_LONG res; #else @@ -655,12 +655,12 @@ return res; } -long ll_os_isatty(long fd) { +long pypy_ll_os_isatty(long fd) { return (int)isatty((int)fd); } #ifdef HAVE_FTRUNCATE -void ll_os_ftruncate(long fd, long length) { /*XXX add longfile support */ +void pypy_ll_os_ftruncate(long fd, long length) { /*XXX add longfile support */ int res; res = ftruncate((int)fd, (off_t)length); if (res < 0) { @@ -669,17 +669,17 @@ } #endif -struct RPyString *ll_os_strerror(int errnum) { +struct RPyString *pypy_ll_os_strerror(int errnum) { char *res; res = strerror(errnum); return RPyString_FromString(res); } -long ll_os_system(struct RPyString * fname) { +long pypy_ll_os_system(struct RPyString * fname) { return system(RPyString_AsString(fname)); } -void ll_os_unlink(struct RPyString * fname) { +void pypy_ll_os_unlink(struct RPyString * fname) { int error = unlink(RPyString_AsString(fname)); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 26 15:07:35 2005 @@ -1,12 +1,11 @@ extdeclarations = """ -declare ccc double %pow(double, double) -declare ccc double %fmod(double, double) declare ccc int %puts(sbyte*) declare ccc uint %strlen(sbyte*) declare ccc int %strcmp(sbyte*, sbyte*) declare ccc sbyte* %memset(sbyte*, int, uint) declare ccc sbyte* %strncpy(sbyte *, sbyte *, int) + %__print_debug_info = internal global bool false %__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" """ @@ -53,7 +52,7 @@ internal fastcc %RPyString* %RPyString_FromString(sbyte* %s) { %lenu = call ccc uint %strlen(sbyte* %s) %len = cast uint %lenu to int - %rpy = call fastcc %RPyString* %RPyString_New__Signed(int %len) + %rpy = call fastcc %RPyString* %pypy_RPyString_New__Signed(int %len) %rpystrptr = getelementptr %RPyString* %rpy, int 0, uint 1, uint 1 %rpystr = cast [0 x sbyte]* %rpystrptr to sbyte* @@ -115,7 +114,7 @@ extfunctions["%%prepare_and_raise_%(exc)s" % locals()] = ((), """ internal fastcc void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { ;XXX %%msg not used right now! - %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() + %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%pypy_instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type @@ -267,10 +266,10 @@ } """ % locals()) -extfunctions["%main"] = ((), """ +extfunctions["%main"] = [(), """ int %main(int %argc, sbyte** %argv) { entry: - %pypy_argv = call fastcc %RPyListOfString* %ll_newlist__listPtrConst_Signed.2(int 0) + %pypy_argv = call fastcc %RPyListOfString* %pypy_ll_newlist__listPtrConst_Signed(int 0) br label %no_exit no_exit: @@ -290,7 +289,7 @@ not_debugging: %rpy = call fastcc %RPyString* %RPyString_FromString(sbyte* %tmp.9) - call fastcc void %ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) + call fastcc void %pypy_ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) br label %next_arg next_arg: @@ -300,8 +299,81 @@ br bool %tmp.2, label %no_exit, label %loopexit loopexit: + %ret = call fastcc int %pypy_entry_point(%structtype.list* %pypy_argv) + ret int %ret +} +"""] + +extfunctions["%main_noargs"] = [(), """ +int %main(int %argc, sbyte** %argv) { +entry: + br label %no_exit + +no_exit: + %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] + %i.0.0 = cast uint %indvar to int + %tmp.8 = getelementptr sbyte** %argv, uint %indvar + %tmp.9 = load sbyte** %tmp.8 + + %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 + %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) + %cond = seteq int %res, 0 + br bool %cond, label %debugging, label %not_debugging + +debugging: + store bool true, bool* %__print_debug_info + br label %next_arg + +not_debugging: + br label %next_arg - %ret = call fastcc int %entry_point(%structtype.list* %pypy_argv) +next_arg: + %inc = add int %i.0.0, 1 + %tmp.2 = setlt int %inc, %argc + %indvar.next = add uint %indvar, 1 + br bool %tmp.2, label %no_exit, label %loopexit + +loopexit: + %ret = call fastcc int %pypy_main_noargs() ret int %ret } -""") +"""] + +extfunctions["%main"] = [(), """ +int %main(int %argc, sbyte** %argv) { +entry: + %pypy_argv = call fastcc %RPyListOfString* %pypy_ll_newlist__listPtrConst_Signed(int 0) + br label %no_exit + +no_exit: + %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] + %i.0.0 = cast uint %indvar to int + %tmp.8 = getelementptr sbyte** %argv, uint %indvar + %tmp.9 = load sbyte** %tmp.8 + + %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 + %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) + %cond = seteq int %res, 0 + br bool %cond, label %debugging, label %not_debugging + +debugging: + store bool true, bool* %__print_debug_info + br label %next_arg + +not_debugging: + %rpy = call fastcc %RPyString* %RPyString_FromString(sbyte* %tmp.9) + call fastcc void %pypy_ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) + br label %next_arg + +next_arg: + %inc = add int %i.0.0, 1 + %tmp.2 = setlt int %inc, %argc + %indvar.next = add uint %indvar, 1 + br bool %tmp.2, label %no_exit, label %loopexit + +loopexit: + + %ret = call fastcc int %pypy_entry_point(%structtype.list* %pypy_argv) + ret int %ret +} +"""] Modified: pypy/dist/pypy/translator/llvm2/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm2/opwriter.py Fri Aug 26 15:07:35 2005 @@ -336,7 +336,7 @@ self.codewriter.invoke_void(functionref, argrefs, argtypes, none_label, exc_label) e = self.db._translator.rtyper.getexceptiondata() - ll_exception_match = '%' + e.ll_exception_match.__name__ + ll_exception_match = '%pypy_' + e.ll_exception_match.__name__ lltype_of_exception_type = ('%structtype.' + e.lltype_of_exception_type.TO.__name__ + '*') From ericvrp at codespeak.net Fri Aug 26 15:23:02 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 26 Aug 2005 15:23:02 +0200 (CEST) Subject: [pypy-svn] r16630 - in pypy/dist/pypy/translator/llvm2: . module Message-ID: <20050826132302.5095A27B69@code1.codespeak.net> Author: ericvrp Date: Fri Aug 26 15:23:01 2005 New Revision: 16630 Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py pypy/dist/pypy/translator/llvm2/genllvm.py pypy/dist/pypy/translator/llvm2/module/support.py Log: fixes to get pypy_ functionname prefix working Modified: pypy/dist/pypy/translator/llvm2/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm2/build_llvm_module.py Fri Aug 26 15:23:01 2005 @@ -35,7 +35,6 @@ ])) def compile_module(module, source_files, object_files, library_files): - print 'QQQQQQQQQQQ compile_module' open("%s_setup.py" % module, "w").write(str(py.code.Source( ''' from distutils.core import setup @@ -52,18 +51,11 @@ cmdexec(cmd) def make_module_from_llvm(llvmfile, pyxfile=None, optimize=True, exe_name=None): - print 'QQQQQQQQQQQ make_module_from_llvm' - print 'QQQQQQQ aaa make_module_from_llvm' include_dir = py.magic.autopath().dirpath() - print 'QQQQQQQ AAA make_module_from_llvm' dirpath = llvmfile.dirpath() - print 'QQQQQQQ BBB make_module_from_llvm' lastdir = path.local() - print 'QQQQQQQ CCC make_module_from_llvm' os.chdir(str(dirpath)) - print 'QQQQQQQ DDD make_module_from_llvm' b = llvmfile.purebasename - print 'QQQQQQQ EEE make_module_from_llvm' if pyxfile: modname = pyxfile.purebasename source_files = [ "%s.c" % modname ] @@ -92,7 +84,6 @@ cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, OPTIMIZATION_SWITCHES, b)] - print 'QQQQQQQ 111 make_module_from_llvm' if False and sys.maxint == 2147483647: #32 bit platform cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) @@ -108,32 +99,21 @@ source_files.append("%s.c" % b) try: - print 'QQQQQQQ 222 make_module_from_llvm' if pyxfile: log.build("modname", modname) c = stdoutcapture.Capture(mixed_out_err = True) log.build("working in", path.local()) - print 'QQQ X 111 make_module_from_llvm' try: - print 'QQQ X 222 make_module_from_llvm' try: - print 'QQQ X 333 make_module_from_llvm' for cmd in cmds: #log.build(cmd) - print 'QQQQQQQQQQQ cmd', cmd cmdexec(cmd) if pyxfile: - print 'QQQ aaa ', cmd make_c_from_pyxfile(pyxfile) - print 'QQQ bbb ', cmd compile_module(modname, source_files, object_files, library_files) - print 'QQQ ccc ', cmd - print 'QQQ ddd ', cmd finally: - print 'QQQ eee ', cmd foutput, ferror = c.done() except: - print 'QQQ fff ', cmd data = 'OUTPUT:\n' + foutput.read() + '\n\nERROR:\n' + ferror.read() if pyxfile: fdump = open("%s.errors" % modname, "w") @@ -141,7 +121,6 @@ fdump.close() log.build(data) raise - print 'QQQQQQQ bbb make_module_from_llvm' # XXX do we need to do some check on fout/ferr? # XXX not a nice way to import a module if pyxfile: @@ -153,10 +132,7 @@ sys.path.pop(0) finally: os.chdir(str(lastdir)) - print 'QQQQQQQ ccc make_module_from_llvm' if pyxfile: - print 'QQQQQQQ ddd make_module_from_llvm' return testmodule if exe_name: - print 'QQQQQQQ eee make_module_from_llvm' return exe_name Modified: pypy/dist/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm2/genllvm.py Fri Aug 26 15:23:01 2005 @@ -423,9 +423,9 @@ def compile_function(function, annotation, **kwds): mod = compile_module(function, annotation, **kwds) - return getattr(mod, function.func_name + "_wrapper") + return getattr(mod, 'pypy_' + function.func_name + "_wrapper") def compile_module_function(function, annotation, **kwds): mod = compile_module(function, annotation, **kwds) - f = getattr(mod, function.func_name + "_wrapper") + f = getattr(mod, 'pypy_' + function.func_name + "_wrapper") return mod, f Modified: pypy/dist/pypy/translator/llvm2/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm2/module/support.py (original) +++ pypy/dist/pypy/translator/llvm2/module/support.py Fri Aug 26 15:23:01 2005 @@ -100,7 +100,7 @@ for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ internal fastcc void %%__prepare_%(exc)s() { - %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%instantiate_%(exc)s() + %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%pypy_instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp store %%RPYTHON_EXCEPTION_VTABLE* %%exception_type, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type From rxe at codespeak.net Fri Aug 26 16:40:04 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 26 Aug 2005 16:40:04 +0200 (CEST) Subject: [pypy-svn] r16632 - pypy/release/0.7.x/pypy/translator/llvm2 Message-ID: <20050826144004.45B7927B69@code1.codespeak.net> Author: rxe Date: Fri Aug 26 16:40:03 2005 New Revision: 16632 Modified: pypy/release/0.7.x/pypy/translator/llvm2/genllvm.py Log: only do the generating c to ll once when running tests (speeds things up a little) Modified: pypy/release/0.7.x/pypy/translator/llvm2/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm2/genllvm.py Fri Aug 26 16:40:03 2005 @@ -27,6 +27,7 @@ from py.process import cmdexec function_count = {} +llcode_header = ll_functions = None def get_ll(ccode, extern_dir, functions=[]): @@ -84,7 +85,8 @@ ll_lines2.append(line) llcode = '\n'.join(ll_lines2) - return llcode.split('implementation') #XXX testing + global llcode_header, ll_functions + llcode_header, ll_functions = llcode.split('implementation') # XXX testing #XXX temp disabled # @@ -158,7 +160,7 @@ return decls def generate_llfile(self, extern_decls): - + #XXX outcommented because we are not puting files here #extern_dir = udir.join("externs") #if extern_dir.check(dir=1): @@ -195,7 +197,7 @@ fns += "ll_time_time ll_time_clock ll_time_sleep ll_floattime".split() fns += "ll_strtod_parts_to_float ll_strtod_formatd".split() - return get_ll(open(p).read(), extern_dir, fns) + get_ll(open(p).read(), extern_dir, fns) def gen_llvm_source(self, func=None): if self.debug: print 'gen_llvm_source begin) ' + time.ctime() @@ -220,7 +222,9 @@ self.translator.rtyper.specialize_more_blocks() self.db.setup_all() - lldeclarations, llimplementation = self.generate_llfile(extern_decls) + if llcode_header is None: + self.generate_llfile(extern_decls) + lldeclarations, llimplementation = llcode_header, ll_functions #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) From ericvrp at codespeak.net Fri Aug 26 17:12:28 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 26 Aug 2005 17:12:28 +0200 (CEST) Subject: [pypy-svn] r16638 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826151228.9CDFD27B69@code1.codespeak.net> Author: ericvrp Date: Fri Aug 26 17:12:26 2005 New Revision: 16638 Added: pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh - copied, changed from r16632, pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh pypy/release/0.7.x/pypy/translator/goal/target_pypy-llvm.py - copied, changed from r16632, pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: * disabled default usage of thread libray for pypy-llvm * added a pypy-llvm target * made standalone name 'pypy-llvm' for this Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Fri Aug 26 17:12:26 2005 @@ -654,7 +654,7 @@ else: if options['-llvm']: print 'Generating and compiling LLVM code...' - c_entry_point = t.llvmcompile(standalone=standalone) + c_entry_point = t.llvmcompile(standalone=standalone, exe_name='pypy-llvm') else: print 'Generating and compiling C code...' c_entry_point = t.ccompile(standalone=standalone, gcpolicy=gcpolicy) From cfbolz at codespeak.net Fri Aug 26 17:17:56 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 17:17:56 +0200 (CEST) Subject: [pypy-svn] r16639 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826151756.2716327B69@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 17:17:54 2005 New Revision: 16639 Modified: pypy/release/0.7.x/pypy/doc/index.txt pypy/release/0.7.x/pypy/doc/translation.txt Log: added section about external function calls. reviews welcome. Modified: pypy/release/0.7.x/pypy/doc/index.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/index.txt (original) +++ pypy/release/0.7.x/pypy/doc/index.txt Fri Aug 26 17:17:54 2005 @@ -36,7 +36,7 @@ `license`_ contains licensing details (basically a straight MIT-license). -.. _FAQ: faq.html +.. _`FAQ`: faq.html .. _parser: parser.html .. _`talks and related projects`: extradoc.html .. _`license`: http://codespeak.net/svn/pypy/dist/LICENSE Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Fri Aug 26 17:17:54 2005 @@ -1172,3 +1172,163 @@ .. include:: _ref.txt + + +External Function Calls +======================= + +There are some functions that we don't want to implement in Python for various +reasons (e.g. if they need to make calls into the OS). These can be +implemented by writing backend code by hand that either implements the +functionality itself or calls appropriate libraries. + +Of course the annotator does not know what types these funtions return so we +need a way to attach fixed annotations to such functions. Additionally for +every such function we need a low level helper function that behaves like the +hand-written backend code so that we can still test a call to such an external +function. + + +Annotating external function calls +---------------------------------- + +All the information about external functions that are important for the +annotation process are written into `pypy/rpython/extfunctable.py`_. There is a +function called ``declare`` that allows to tell the annotator the return type +of these functions and to attach a low level dummy implementation:: + + declare(funct, annotation_factory, lowlevel_dummy) + +Here ``funct`` is the funtion that is supposed to be implemented in the +backend, ``annotation_factory`` is a function that returns an appropriate +annotation of the return value (an instance of a primitive type is also ok, so +you can do ``declare(func, int...)``), lowlevel_dummy is a string of the form +``module/ll_function`` that specifies where the low level dummy function is +defined. Here ``module`` means a Python file in `pypy/rpython/module/`_ and +``ll_function`` is a low level function defined in that file. + +If the annotator discovers a call to ``func`` it does not try to follow that +call further (even though that might be possible if the function is written in +Python) but annotates it with the given type immediately. The `RPython Typer`_ +replaces calls to ``func`` with calls to the function +``module.ll_function``. The backend is supposed to replace calls to functions +to ``module.ll_function`` by whatever code it finds appropriate. + +.. _`pypy/rpython/extfunctable.py`: ../rpython/extfunctable.py +.. _`pypy/rpython/module/`: ../rpython/module + + + +Implementating low level replacement functions in Python +--------------------------------------------------------- + +The dummy low level replacement functions are there to implement the external +function on the low level. In contrast to the original function they should +take arguments that are of `low-level type`_. Most of the times they are +implemented by calling appropriate low level to high level conversion +functions and then calling the original funtion again. + +If the function is supposed to really be implemented by the backend then the +low level function should have an attribute ``.suggested_primitive = True`` +attached. If this is not the case the low level function itself will be +translated and used. + + +Implementing the external functions in the C backend +---------------------------------------------------- + +When the C-backend produces C code and finds a function call to one of the +dummy functions it replaces the call to it by a call to a function written in +C. This mapping is done in the file `pypy/translator/c/extfunc.py`_. In there +is a dictionary called ``EXTERNALS`` which contains mappings from dummy +functions to strings:: + + EXTERNAL = { + module.ll_function: "LL_c_name_of_function" + ... + } + +Here ``LL_c_name_of_function`` is the name of the C function that implements +the functionality of the ``module.ll_function``. These C implementation are +found in the directory `pypy/translator/c/src/`_. + +It sometimes neccessary to access a certain function or type that is written +in Python from the C code you write by hand (for example for constructing the +return value in the correct low level type). This can be a problem because the +C backend mangels names to prevent clashes. To get a certain low level type +under a fixed name the function ``predeclare_common_types`` needs to be +changed. This function is a generator that yields tuples of the form +``('c_name', LLTYPE)``. This makes the genc assign the name ``c_name`` to the +type ``LLTYPE``. Similarly all the function defined in +``predeclare_utility_functions`` are automacially made accessible under their +name in C. + +.. _`pypy/translator/c/extfunc.py`: ../translator/c/extfunc.py +.. _`pypy/translator/c/src/`: ../translator/c/src/ + + +Example +------- + +To make this clearer the following shows all the relevant pieces that are +needed for implementing os.open. It is implemented in the following way at +interp-level in the `mixed posix module`_:: + + def open(space, fname, flag, mode=0777): + try: + fd = os.open(fname, flag, mode) + except OSError, e: + raise wrap_oserror(space, e) + return space.wrap(fd) + open.unwrap_spec = [ObjSpace, str, int, int] + + +If the annotator tries to annotate this function it will use the declaration +it finds in the file `pypy/rpython/extfunctable.py`_:: + + declare(os.open, int , 'll_os/open') + +This means that the function returns an int and that the dummy low level +function can be found in `pypy/rpython/module/ll_os.py`_:: + + def ll_os_open(fname, flag, mode): + return os.open(from_rstr(fname), flag, mode) + ll_os_open.suggested_primitive = True + +The ``suggested_primitive`` attribute of the ``ll_os_open`` is set to True, +because it is reasonable that this function is written directly in the backend. +If the C backend encounters a call to ``ll_os_open`` somewhere in the code it +checks the ``EXTERNALS`` table in `pypy/translator/c/extfunc.py`_. The +relevant part for ``os.open`` is:: + + from pypy.rpython.module import ll_os + EXTERNALS = { + ... + ll_os.ll_os_open: 'LL_os_open', + ... + } + +The `LL_os_open` function is implemented in the file +`pypy/translator/c/src/ll_os.h`_:: + + int LL_os_open(RPyString *filename, int flag, int mode) + { + char buf[PATH_MAX]; + int fd, namelen = RPyString_Size(filename); + if (namelen >= PATH_MAX) { + RPYTHON_RAISE_OSERROR(ENAMETOOLONG); + return -1; + } + else { + memcpy(buf, RPyString_AsString(filename), namelen); + buf[namelen] = 0; + fd = open(buf, flag, mode); + if (fd < 0) + RPYTHON_RAISE_OSERROR(errno); + return fd; + } + } + +.. _`mixed posix module`: ../module/posix/ +.. _`pypy/rpython/module/ll_os.py`: ../rpython/module/ll_os.py +.. _`pypy/translator/c/src/ll_os.h`: ../translator/c/src/ll_os.h \ No newline at end of file From pedronis at codespeak.net Fri Aug 26 17:22:56 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 17:22:56 +0200 (CEST) Subject: [pypy-svn] r16640 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826152256.5B4BB27B69@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 17:22:54 2005 New Revision: 16640 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: change the default to not using the snapshot, introduced instead a -use-snapshot option to get the old behavior Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Fri Aug 26 17:22:54 2005 @@ -28,8 +28,8 @@ -d Enable recording of annotator debugging information -huge=% Threshold in the number of functions after which only a local call graph and not a full one is displayed - -no-snapshot - Don't redirect imports to the translation snapshot + -use-snapshot + Redirect imports to the translation snapshot -save filename saves the translator to a file. The file type can either be .py or .zip (recommended). @@ -47,7 +47,7 @@ """ import autopath, sys, os -if '-no-snapshot' not in sys.argv: +if '-use-snapshot' in sys.argv: # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx basedir = autopath.this_dir @@ -55,7 +55,7 @@ if not os.path.isdir(pypy_translation_snapshot_dir): print """ - Translation is performed on a specific revision of PyPy which lives on + Translation will be performed on a specific revision of PyPy which lives on a branch. This needs to be checked out into translator/goal with: svn co http://codespeak.net/svn/pypy/branch/pypy-translation-snapshot @@ -352,7 +352,7 @@ '-no-o': False, '-tcc': False, '-d': False, - '-no-snapshot' : False, + '-use-snapshot' : False, '-load': False, '-save': False, '-fork': False, From cfbolz at codespeak.net Fri Aug 26 17:25:45 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 17:25:45 +0200 (CEST) Subject: [pypy-svn] r16641 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826152545.0F00827B69@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 17:25:44 2005 New Revision: 16641 Removed: pypy/release/0.7.x/pypy/doc/ext-functions-draft.txt Log: removing ext-functions-draft. it's info was incorporated into translation.txt. From ludal at codespeak.net Fri Aug 26 17:28:05 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 17:28:05 +0200 (CEST) Subject: [pypy-svn] r16642 - in pypy/release/0.7.x/pypy: interpreter interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050826152805.A99F327B69@code1.codespeak.net> Author: ludal Date: Fri Aug 26 17:28:01 2005 New Revision: 16642 Modified: pypy/release/0.7.x/pypy/interpreter/pycompiler.py pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py Log: - hopefully fix (or include) some line numbers in error reporting - better translate syntax errors from the parser - fixes both stable and _stable compilers Modified: pypy/release/0.7.x/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pycompiler.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pycompiler.py Fri Aug 26 17:28:01 2005 @@ -194,8 +194,13 @@ try: parse_result = internal_pypy_parse(source, mode, True, flags) except ParseError, e: - raise OperationError(space.w_SyntaxError, - e.wrap_info(space, filename)) + w_synerr = space.newtuple([space.wrap(e.msg), + space.newtuple([space.wrap(filename), + space.wrap(e.lineno), + space.wrap(e.offset), + space.wrap("") + ])]) + raise OperationError(space.w_SyntaxError, w_synerr) return self.compile_parse_result(parse_result, filename, mode, flags) def compile_parse_result(self, parse_result, filename, mode, flags): @@ -213,7 +218,7 @@ from pypy.interpreter.stablecompiler.transformer import Transformer space = self.space try: - transformer = Transformer() + transformer = Transformer(filename) tree = transformer.compile_node(tuples) stablecompiler.misc.set_filename(filename, tree) flag_names = get_flag_names( flags ) @@ -420,8 +425,17 @@ space.wrap(e.offset), space.wrap(e.text)])]) raise OperationError(space.w_SyntaxError, w_synerr) + except UnicodeDecodeError, e: + # TODO use a custom UnicodeError + raise OperationError(space.w_UnicodeDecodeError, space.newtuple([ + space.wrap(e.encoding), space.wrap(e.object), space.wrap(e.start), + space.wrap(e.end), space.wrap(e.reason)])) except ValueError,e: - raise OperationError(space.w_ValueError,space.wrap(str(e))) + if e.__class__ != ValueError: + extra_msg = "(Really go %s)" % e.__class__.__name__ + else: + extra_msg = "" + raise OperationError(space.w_ValueError,space.wrap(str(e)+extra_msg)) except TypeError,e: raise raise OperationError(space.w_TypeError,space.wrap(str(e))) Modified: pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py Fri Aug 26 17:28:01 2005 @@ -109,8 +109,9 @@ tree = parsefile(fileob | filename) """ - def __init__(self): + def __init__(self, filename): self._dispatch = {} + self.filename = filename for value, name in symbol.sym_name.items(): if hasattr(self, name): self._dispatch[value] = getattr(self, name) @@ -125,6 +126,13 @@ } self.encoding = None + def syntaxerror( self, msg, node ): + offset = 0 + text = "return x!" + lineno = extractLineNo( node ) + args = ( self.filename, lineno, offset, text ) + raise SyntaxError( msg, args ) + def transform(self, tree): """Transform an AST into a modified parse tree.""" if not (isinstance(tree, tuple) or isinstance(tree, list)): @@ -936,7 +944,7 @@ l = self.com_node(node) if l.__class__ in (Name, Slice, Subscript, Getattr): return l - raise SyntaxError, "can't assign to %s" % l.__class__.__name__ + self.syntaxerror( "can't assign to %s" % l.__class__.__name__, node) def com_assign(self, node, assigning): # return a node suitable for use as an "lvalue" @@ -949,17 +957,17 @@ node = node[1] elif t in _assign_types: if len(node) > 2: - raise SyntaxError, "can't assign to operator" + self.syntaxerror( "can't assign to operator", node) node = node[1] elif t == symbol.power: if node[1][0] != symbol.atom: - raise SyntaxError, "can't assign to operator" + self.syntaxerror( "can't assign to operator", node) if len(node) > 2: primary = self.com_node(node[1]) for i in range(2, len(node)-1): ch = node[i] if ch[0] == token.DOUBLESTAR: - raise SyntaxError, "can't assign to operator" + self.syntaxerror( "can't assign to operator", node) primary = self.com_apply_trailer(primary, ch) return self.com_assign_trailer(primary, node[-1], assigning) @@ -969,24 +977,24 @@ if t == token.LPAR: node = node[2] if node[0] == token.RPAR: - raise SyntaxError, "can't assign to ()" + self.syntaxerror( "can't assign to ()", node) elif t == token.LSQB: node = node[2] if node[0] == token.RSQB: - raise SyntaxError, "can't assign to []" + self.syntaxerror( "can't assign to []", node) return self.com_assign_list(node, assigning) elif t == token.NAME: return self.com_assign_name(node[1], assigning) else: - raise SyntaxError, "can't assign to literal" + self.syntaxerror( "can't assign to literal", node) else: - raise SyntaxError, "bad assignment" + self.syntaxerror( "bad assignment", node) def com_assign_tuple(self, node, assigning): assigns = [] if len(node)>=3: if node[2][0] == symbol.gen_for: - raise SyntaxError("assign to generator expression not possible") + self.syntaxerror("assign to generator expression not possible", node) for i in range(1, len(node), 2): assigns.append(self.com_assign(node[i], assigning)) return AssTuple(assigns, lineno=extractLineNo(node)) @@ -996,7 +1004,7 @@ for i in range(1, len(node), 2): if i + 1 < len(node): if node[i + 1][0] == symbol.list_for: - raise SyntaxError, "can't assign to list comprehension" + self.syntaxerror( "can't assign to list comprehension", node) assert node[i + 1][0] == token.COMMA, node[i + 1] assigns.append(self.com_assign(node[i], assigning)) return AssList(assigns, lineno=extractLineNo(node)) @@ -1012,10 +1020,10 @@ return self.com_subscriptlist(primary, node[2], assigning) if t == token.LPAR: if assigning==OP_DELETE: - raise SyntaxError, "can't delete function call" + self.syntaxerror( "can't delete function call", node) else: - raise SyntaxError, "can't assign to function call" - raise SyntaxError, "unknown trailer type: %s" % t + self.syntaxerror( "can't assign to function call", node) + self.syntaxerror( "unknown trailer type: %s" % t, node) def com_assign_attr(self, primary, node, assigning): return AssAttr(primary, node[1], assigning, lineno=node[-1]) @@ -1091,9 +1099,9 @@ else: node = self.com_list_iter(node[3]) else: - raise SyntaxError, \ - ("unexpected list comprehension element: %s %d" - % (node, lineno)) + self.syntaxerror( + "unexpected list comprehension element: %s %d" + % (node, lineno), node) return ListComp(expr, fors, lineno=lineno) def com_list_iter(self, node): @@ -1135,9 +1143,9 @@ else: node = self.com_gen_iter(node[3]) else: - raise SyntaxError, \ - ("unexpected generator expression element: %s %d" - % (node, lineno)) + self.syntaxerror( + "unexpected generator expression element: %s %d" + % (node, lineno), node) fors[0].is_outmost = True return GenExpr(GenExprInner(expr, fors), lineno=lineno) @@ -1162,11 +1170,11 @@ if t == token.LSQB: return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY) - raise SyntaxError, 'unknown node type: %s' % t + self.syntaxerror( 'unknown node type: %s' % t, primaryNode) def com_select_member(self, primaryNode, nodelist): if nodelist[0] != token.NAME: - raise SyntaxError, "member must be a name" + self.syntaxerror( "member must be a name", primaryNode) return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) def com_call_function(self, primaryNode, nodelist): @@ -1185,7 +1193,7 @@ and len(node) == 3 and node[2][0] == symbol.gen_for: # allow f(x for x in y), but reject f(x for x in y, 1) # should use f((x for x in y), 1) instead of f(x for x in y, 1) - raise SyntaxError, 'generator expression needs parenthesis' + self.syntaxerror( 'generator expression needs parenthesis', primaryNode) args.append(result) else: @@ -1201,14 +1209,14 @@ i = i + 3 if tok[0]==token.STAR: if star_node is not None: - raise SyntaxError, 'already have the varargs indentifier' + self.syntaxerror( 'already have the varargs indentifier', primaryNode) star_node = self.com_node(ch) elif tok[0]==token.DOUBLESTAR: if dstar_node is not None: - raise SyntaxError, 'already have the kwargs indentifier' + self.syntaxerror( 'already have the kwargs indentifier', primaryNode) dstar_node = self.com_node(ch) else: - raise SyntaxError, 'unknown node type: %s' % tok + self.syntaxerror( 'unknown node type: %s' % tok, primaryNode) return CallFunc(primaryNode, args, star_node, dstar_node, lineno=extractLineNo(nodelist)) @@ -1218,14 +1226,14 @@ return 0, self.com_generator_expression(test, nodelist[2]) if len(nodelist) == 2: if kw: - raise SyntaxError, "non-keyword arg after keyword arg" + self.syntaxerror( "non-keyword arg after keyword arg", nodelist[0]) return 0, self.com_node(nodelist[1]) result = self.com_node(nodelist[3]) n = nodelist[1] while len(n) == 2 and n[0] != token.NAME: n = n[1] if n[0] != token.NAME: - raise SyntaxError, "keyword can't be an expression (%s)"%n[0] + self.syntaxerror( "keyword can't be an expression (%s)"%n[0], n) node = Keyword(n[1], result, lineno=n[2]) return 1, node Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py Fri Aug 26 17:28:01 2005 @@ -10,7 +10,7 @@ from _stablecompiler.transformer import Transformer def applevelcompile(tuples, filename, mode, flag_names ): - transformer = Transformer() + transformer = Transformer(filename) tree = transformer.compile_node(tuples) set_filename(filename, tree) if mode == 'exec': Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py Fri Aug 26 17:28:01 2005 @@ -106,8 +106,9 @@ tree = parsefile(fileob | filename) """ - def __init__(self): + def __init__(self, filename): self._dispatch = {} + self.filename = filename for value, name in symbol.sym_name.items(): if hasattr(self, name): self._dispatch[value] = getattr(self, name) @@ -122,6 +123,13 @@ } self.encoding = None + def syntaxerror( self, msg, node ): + offset = 0 + text = "return x!" + lineno = extractLineNo( node ) + args = ( self.filename, lineno, offset, text ) + raise SyntaxError( msg, args ) + def transform(self, tree): """Transform an AST into a modified parse tree.""" if not (isinstance(tree, tuple) or isinstance(tree, list)): @@ -932,7 +940,7 @@ l = self.com_node(node) if l.__class__ in (Name, Slice, Subscript, Getattr): return l - raise SyntaxError, "can't assign to %s" % l.__class__.__name__ + self.syntaxerror( "can't assign to %s" % l.__class__.__name__, node) def com_assign(self, node, assigning): # return a node suitable for use as an "lvalue" @@ -945,17 +953,17 @@ node = node[1] elif t in _assign_types: if len(node) > 2: - raise SyntaxError, "can't assign to operator" + self.syntaxerror( "can't assign to operator", node) node = node[1] elif t == symbol.power: if node[1][0] != symbol.atom: - raise SyntaxError, "can't assign to operator" + self.syntaxerror( "can't assign to operator", node) if len(node) > 2: primary = self.com_node(node[1]) for i in range(2, len(node)-1): ch = node[i] if ch[0] == token.DOUBLESTAR: - raise SyntaxError, "can't assign to operator" + self.syntaxerror( "can't assign to operator", node) primary = self.com_apply_trailer(primary, ch) return self.com_assign_trailer(primary, node[-1], assigning) @@ -965,24 +973,24 @@ if t == token.LPAR: node = node[2] if node[0] == token.RPAR: - raise SyntaxError, "can't assign to ()" + self.syntaxerror( "can't assign to ()", node) elif t == token.LSQB: node = node[2] if node[0] == token.RSQB: - raise SyntaxError, "can't assign to []" + self.syntaxerror( "can't assign to []", node) return self.com_assign_list(node, assigning) elif t == token.NAME: return self.com_assign_name(node[1], assigning) else: - raise SyntaxError, "can't assign to literal" + self.syntaxerror( "can't assign to literal", node) else: - raise SyntaxError, "bad assignment" + self.syntaxerror( "bad assignment", node) def com_assign_tuple(self, node, assigning): assigns = [] if len(node)>=3: if node[2][0] == symbol.gen_for: - raise SyntaxError("assign to generator expression not possible") + self.syntaxerror("assign to generator expression not possible", node) for i in range(1, len(node), 2): assigns.append(self.com_assign(node[i], assigning)) return AssTuple(assigns, lineno=extractLineNo(node)) @@ -992,7 +1000,7 @@ for i in range(1, len(node), 2): if i + 1 < len(node): if node[i + 1][0] == symbol.list_for: - raise SyntaxError, "can't assign to list comprehension" + self.syntaxerror( "can't assign to list comprehension", node) assert node[i + 1][0] == token.COMMA, node[i + 1] assigns.append(self.com_assign(node[i], assigning)) return AssList(assigns, lineno=extractLineNo(node)) @@ -1008,10 +1016,10 @@ return self.com_subscriptlist(primary, node[2], assigning) if t == token.LPAR: if assigning==OP_DELETE: - raise SyntaxError, "can't delete function call" + self.syntaxerror( "can't delete function call", node) else: - raise SyntaxError, "can't assign to function call" - raise SyntaxError, "unknown trailer type: %s" % t + self.syntaxerror( "can't assign to function call", node) + self.syntaxerror( "unknown trailer type: %s" % t, node) def com_assign_attr(self, primary, node, assigning): return AssAttr(primary, node[1], assigning, lineno=node[-1]) @@ -1087,9 +1095,9 @@ else: node = self.com_list_iter(node[3]) else: - raise SyntaxError, \ - ("unexpected list comprehension element: %s %d" - % (node, lineno)) + self.syntaxerror( + "unexpected list comprehension element: %s %d" + % (node, lineno), node) return ListComp(expr, fors, lineno=lineno) def com_list_iter(self, node): @@ -1131,9 +1139,9 @@ else: node = self.com_gen_iter(node[3]) else: - raise SyntaxError, \ - ("unexpected generator expression element: %s %d" - % (node, lineno)) + self.syntaxerror( + "unexpected generator expression element: %s %d" + % (node, lineno), node) fors[0].is_outmost = True return GenExpr(GenExprInner(expr, fors), lineno=lineno) @@ -1158,11 +1166,11 @@ if t == token.LSQB: return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY) - raise SyntaxError, 'unknown node type: %s' % t + self.syntaxerror( 'unknown node type: %s' % t, primaryNode) def com_select_member(self, primaryNode, nodelist): if nodelist[0] != token.NAME: - raise SyntaxError, "member must be a name" + self.syntaxerror( "member must be a name", primaryNode) return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) def com_call_function(self, primaryNode, nodelist): @@ -1181,7 +1189,7 @@ and len(node) == 3 and node[2][0] == symbol.gen_for: # allow f(x for x in y), but reject f(x for x in y, 1) # should use f((x for x in y), 1) instead of f(x for x in y, 1) - raise SyntaxError, 'generator expression needs parenthesis' + self.syntaxerror( 'generator expression needs parenthesis', primaryNode) args.append(result) else: @@ -1197,14 +1205,14 @@ i = i + 3 if tok[0]==token.STAR: if star_node is not None: - raise SyntaxError, 'already have the varargs indentifier' + self.syntaxerror( 'already have the varargs indentifier', primaryNode) star_node = self.com_node(ch) elif tok[0]==token.DOUBLESTAR: if dstar_node is not None: - raise SyntaxError, 'already have the kwargs indentifier' + self.syntaxerror( 'already have the kwargs indentifier', primaryNode) dstar_node = self.com_node(ch) else: - raise SyntaxError, 'unknown node type: %s' % tok + self.syntaxerror( 'unknown node type: %s' % tok, primaryNode) return CallFunc(primaryNode, args, star_node, dstar_node, lineno=extractLineNo(nodelist)) @@ -1214,14 +1222,14 @@ return 0, self.com_generator_expression(test, nodelist[2]) if len(nodelist) == 2: if kw: - raise SyntaxError, "non-keyword arg after keyword arg" + self.syntaxerror( "non-keyword arg after keyword arg", nodelist[0]) return 0, self.com_node(nodelist[1]) result = self.com_node(nodelist[3]) n = nodelist[1] while len(n) == 2 and n[0] != token.NAME: n = n[1] if n[0] != token.NAME: - raise SyntaxError, "keyword can't be an expression (%s)"%n[0] + self.syntaxerror( "keyword can't be an expression (%s)"%n[0], n) node = Keyword(n[1], result, lineno=n[2]) return 1, node From ac at codespeak.net Fri Aug 26 17:32:17 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 26 Aug 2005 17:32:17 +0200 (CEST) Subject: [pypy-svn] r16643 - pypy/release/0.7.x/pypy/objspace/std Message-ID: <20050826153217.66E9927B69@code1.codespeak.net> Author: ac Date: Fri Aug 26 17:32:16 2005 New Revision: 16643 Modified: pypy/release/0.7.x/pypy/objspace/std/unicodeobject.py Log: Fix IndexError when doing repr on a string ending with a UTF-16 surrogate. Modified: pypy/release/0.7.x/pypy/objspace/std/unicodeobject.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/std/unicodeobject.py (original) +++ pypy/release/0.7.x/pypy/objspace/std/unicodeobject.py Fri Aug 26 17:32:16 2005 @@ -939,25 +939,26 @@ j += 1 continue if code >= 0xD800 and code < 0xDC00: - ch2 = chars[j+1] - code2 = ord(ch2) - if code2 >= 0xDC00 and code2 <= 0xDFFF: - code = (((code & 0x03FF) << 10) | (code2 & 0x03FF)) + 0x00010000 - if i + 12 > len(result): - result.extend(['\0'] * 100) - result[i] = '\\' - result[i + 1] = "U" - result[i + 2] = hexdigits[(code >> 28) & 0xf] - result[i + 3] = hexdigits[(code >> 24) & 0xf] - result[i + 4] = hexdigits[(code >> 20) & 0xf] - result[i + 5] = hexdigits[(code >> 16) & 0xf] - result[i + 6] = hexdigits[(code >> 12) & 0xf] - result[i + 7] = hexdigits[(code >> 8) & 0xf] - result[i + 8] = hexdigits[(code >> 4) & 0xf] - result[i + 9] = hexdigits[(code >> 0) & 0xf] - i += 10 - j += 2 - continue + if j < size - 1: + ch2 = chars[j+1] + code2 = ord(ch2) + if code2 >= 0xDC00 and code2 <= 0xDFFF: + code = (((code & 0x03FF) << 10) | (code2 & 0x03FF)) + 0x00010000 + if i + 12 > len(result): + result.extend(['\0'] * 100) + result[i] = '\\' + result[i + 1] = "U" + result[i + 2] = hexdigits[(code >> 28) & 0xf] + result[i + 3] = hexdigits[(code >> 24) & 0xf] + result[i + 4] = hexdigits[(code >> 20) & 0xf] + result[i + 5] = hexdigits[(code >> 16) & 0xf] + result[i + 6] = hexdigits[(code >> 12) & 0xf] + result[i + 7] = hexdigits[(code >> 8) & 0xf] + result[i + 8] = hexdigits[(code >> 4) & 0xf] + result[i + 9] = hexdigits[(code >> 0) & 0xf] + i += 10 + j += 2 + continue if code >= 0x100: result[i] = '\\' From hpk at codespeak.net Fri Aug 26 17:41:49 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 17:41:49 +0200 (CEST) Subject: [pypy-svn] r16645 - pypy/release/0.7.x Message-ID: <20050826154149.BEDF827B64@code1.codespeak.net> Author: hpk Date: Fri Aug 26 17:41:49 2005 New Revision: 16645 Modified: pypy/release/0.7.x/README Log: first stab at getting the README adjusted for 0.7 Modified: pypy/release/0.7.x/README ============================================================================== --- pypy/release/0.7.x/README (original) +++ pypy/release/0.7.x/README Fri Aug 26 17:41:49 2005 @@ -1,36 +1,32 @@ -PyPy: Python in Python implementation / Version 0.6 -=================================================== +PyPy: Python in Python implementation / Version 0.7.0 +======================================================= -Welcome to PyPy! PyPy-0.6 is the first public release -after two years of spare-time and half a year of European Union -funded development from a multitude of people and organizations. +Welcome to PyPy! PyPy-0.7.0 marks the first public release +that allows to build a self-contained Python implementation +that does not depend or run on top of CPython anymore. We invested a lot of time in improving the documentation and website and thus invite you to head over to our getting-started document - pypy/documentation/getting_started.txt or - http://codespeak.net/pypy/index.cgi?getting-started + pypy/doc/getting-started.txt (local if you got a tarball) + + http://codespeak.net/pypy/dist/pypy/doc/getting-started.html which gives you many good starting and entry points into playing with PyPy. It will also point you to our -documentation section of which you can find the source ReST -files in the following directory: - - pypy/documentation/index.txt or - http://codespeak.net/pypy/index.cgi?doc +documentation section which is generated from information +in the pypy/doc directory. Our online release announcement has some more -information about the specific PyPy-0.6 release: - - pypy/documentation/release-0.6.txt or - http://codespeak.net/pypy/index.cgi?doc/release-0.6.html +information about the specific PyPy-0.7.0 release: -Please freel free to contact or join us in one of the ways -listed in our contact page: + pypy/documentation/release-0.7.0.txt or + http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html - pypy/documentation/website/contact.txt or - http://codespeak.net/pypy/index.cgi?contact +Please note that the last 9 months of PyPy development +have been funded by the European Union through its research +programme. Enjoy and send us feedback! From hpk at codespeak.net Fri Aug 26 17:44:37 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 17:44:37 +0200 (CEST) Subject: [pypy-svn] r16646 - in pypy/release/0.7.x: . pypy/doc/tool Message-ID: <20050826154437.8F18327B64@code1.codespeak.net> Author: hpk Date: Fri Aug 26 17:44:36 2005 New Revision: 16646 Modified: pypy/release/0.7.x/LICENSE pypy/release/0.7.x/pypy/doc/tool/makecontributor.py Log: issue52 testing - shortened the LICENSE file to adjust to current copyright holders generated from makecontributor.py script. Some people were removed that explicitely said so or only did very minor contributions. - moved py lib's licensing info into its own py/LICENSE still there is some LICENSING info missing at least in module/unicodedata. Arre is currently looking into that. Modified: pypy/release/0.7.x/LICENSE ============================================================================== --- pypy/release/0.7.x/LICENSE (original) +++ pypy/release/0.7.x/LICENSE Fri Aug 26 17:44:36 2005 @@ -1,9 +1,9 @@ -License for files in the pypy and py directory -============================================== +License for files in the pypy/ directory +================================================== Except when otherwise stated (look for LICENSE files in directories or information at the beginning of each file) all software and -documentation in the 'pypy' and 'py' directories is licensed as follows: +documentation in the 'pypy' directories is licensed as follows: The MIT License @@ -37,37 +37,24 @@ Armin Rigo Samuele Pedroni Holger Krekel - Michael Hudson Christian Tismer + Michael Hudson + Carl Friedrich Bolz + Eric van Riet Paap + Richard Emslie + Anders Chrigstrom Seo Sanghyeon Alex Martelli - Stefan Schwarzer + Anders Lehmann Patrick Maupin - Carl Friedrich Bolz + Ludovic Aubry Bob Ippolito - Anders Chrigstrom + Adrien Di Mascio Jacob Hallen - Marius Gedminas Laura Creighton + Marius Gedminas + Niklaus Haldimann Guido van Rossum - Richard Emslie - Ludovic Aubry - Adrien Di Mascio - Stephan Diehl <> - Dinu Gherman - Guenter Jantzen - Anders Lehmann - Rocco Moretti - Olivier Dormond - Brian Dorsey - Jonathan David Riehl - Andreas Friedge - Jens-Uwe Mager - Alan McIntyre - Lutz Paelike - Jacek Generowicz - Ben Young - Michael Chermside Heinrich-Heine University, Germany AB Strakt, Sweden @@ -77,31 +64,12 @@ DFKI GmbH, Germany -py lib Copyright holders, 2003-2005 ------------------------------------ - -Except when otherwise stated (look for LICENSE files or information at -the beginning of each file) the files in the 'py' directory are -copyrighted by one or more of the following people and organizations: - - Holger Krekel - merlinux GmbH, Germany - Armin Rigo - Jan Balster - -Contributors include:: - - Ian Bicking - Grig Gheorghiu - Bob Ippolito - - -License for 'lib-python/2.3.4' and 'lib-python/2.3.4-modified' +License for 'lib-python/2.4.1' and 'lib-python/2.4.1-modified' ============================================================== -Except when otherwise stated (look for LICENSE files or information at -the beginning of each file) the files in the 'lib-python/2.3.4' -and 'lib-python/2.3.4-modified' directories are all copyrighted -by the Python Software Foundation and licensed under the Python -Software License of which you can find a copy here: +Except when otherwise stated (look for LICENSE files or +copyright/license information at the beginning of each file) the files +in the 'lib-python/2.4.1' and 'lib-python/2.4.1-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 Modified: pypy/release/0.7.x/pypy/doc/tool/makecontributor.py ============================================================================== --- pypy/release/0.7.x/pypy/doc/tool/makecontributor.py (original) +++ pypy/release/0.7.x/pypy/doc/tool/makecontributor.py Fri Aug 26 17:44:36 2005 @@ -26,6 +26,9 @@ import uconf # http://codespeak.net/svn/uconf/dist/uconf for author, count in items: - realname = uconf.system.User(author).realname # only works on codespeak - print " ", realname + user = uconf.system.User(author) + realname = user.realname + email = user.email + #print "%5d" % count, " ", realname, "<%s>" % email + print " ", realname, "<%s>" % email From ac at codespeak.net Fri Aug 26 17:47:40 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 26 Aug 2005 17:47:40 +0200 (CEST) Subject: [pypy-svn] r16649 - pypy/release/0.7.x/pypy/module/unicodedata Message-ID: <20050826154740.4EB0327B64@code1.codespeak.net> Author: ac Date: Fri Aug 26 17:47:40 2005 New Revision: 16649 Added: pypy/release/0.7.x/pypy/module/unicodedata/LICENSE Log: Add license condions for files from unicode consortium. Added: pypy/release/0.7.x/pypy/module/unicodedata/LICENSE ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/module/unicodedata/LICENSE Fri Aug 26 17:47:40 2005 @@ -0,0 +1,10 @@ +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 + EastAsianWidth-3.2.0.txt + EastAsianWidth-4.1.0.txt + UnicodeData-3.2.0.txt + UnicodeData-4.1.0.txt From cfbolz at codespeak.net Fri Aug 26 17:49:46 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 17:49:46 +0200 (CEST) Subject: [pypy-svn] r16650 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826154946.B675127B64@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 17:49:45 2005 New Revision: 16650 Modified: pypy/release/0.7.x/pypy/doc/translation.txt Log: some small hints how to test external functions + example. Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Fri Aug 26 17:49:45 2005 @@ -1266,6 +1266,23 @@ .. _`pypy/translator/c/extfunc.py`: ../translator/c/extfunc.py .. _`pypy/translator/c/src/`: ../translator/c/src/ +Testing +------- + +It's not always trivial to properly test that all the information that is +needed for a given external function is correct. Usually for a given function +you test at least two different things: Once the dummy low level function by +calling it directly. This is usually done in `pypy/rpython/module/test`_ by +just calling the low level function with appropriately constructed arguments +directly. In addition there should be test that actually tries to translate +a function calling the external function to backend code, compile and run +it. This makes sure that the annotator gets the annotation right and that the +backend code is correct. For the C backend this is done in +`pypy/translator/c/test/test_extfunc.py`_. + +.. _`pypy/rpython/module/test`: ../rpython/module/test/ +.. _`pypy/translator/c/test/test_extfunc.py`: ../translator/c/test/test_extfunc.py + Example ------- @@ -1329,6 +1346,20 @@ } } +One test for all this can be found in +`pypy/translator/c/test/test_extfunc.py`_:: + + def test_os_open(): + tmpfile = str(udir.join('test_os_open.txt')) + def does_stuff(): + fd = os.open(tmpfile, os.O_WRONLY | os.O_CREAT, 0777) + return fd + f1 = compile(does_stuff, []) + fd = f1() + os.close(fd) + assert os.path.exists(tmpfile) + + .. _`mixed posix module`: ../module/posix/ .. _`pypy/rpython/module/ll_os.py`: ../rpython/module/ll_os.py .. _`pypy/translator/c/src/ll_os.h`: ../translator/c/src/ll_os.h \ No newline at end of file From rxe at codespeak.net Fri Aug 26 17:52:16 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 26 Aug 2005 17:52:16 +0200 (CEST) Subject: [pypy-svn] r16651 - in pypy/release/0.7.x/pypy/translator: . llvm llvm/demo llvm/module llvm/test llvm/tool llvm2 test Message-ID: <20050826155216.861F427B64@code1.codespeak.net> Author: rxe Date: Fri Aug 26 17:52:10 2005 New Revision: 16651 Added: pypy/release/0.7.x/pypy/translator/llvm/ - copied from r16639, pypy/release/0.7.x/pypy/translator/llvm2/ pypy/release/0.7.x/pypy/translator/llvm/__init__.py - copied unchanged from r16650, pypy/release/0.7.x/pypy/translator/llvm2/__init__.py pypy/release/0.7.x/pypy/translator/llvm/arraynode.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/arraynode.py pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/build_llvm_module.py pypy/release/0.7.x/pypy/translator/llvm/codewriter.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/codewriter.py pypy/release/0.7.x/pypy/translator/llvm/database.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/database.py pypy/release/0.7.x/pypy/translator/llvm/demo/ - copied from r16650, pypy/release/0.7.x/pypy/translator/llvm2/demo/ pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/extfuncnode.py pypy/release/0.7.x/pypy/translator/llvm/funcnode.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/funcnode.py pypy/release/0.7.x/pypy/translator/llvm/genllvm.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/genllvm.py pypy/release/0.7.x/pypy/translator/llvm/log.py - copied unchanged from r16650, pypy/release/0.7.x/pypy/translator/llvm2/log.py pypy/release/0.7.x/pypy/translator/llvm/module/ - copied from r16650, pypy/release/0.7.x/pypy/translator/llvm2/module/ pypy/release/0.7.x/pypy/translator/llvm/node.py - copied unchanged from r16650, pypy/release/0.7.x/pypy/translator/llvm2/node.py pypy/release/0.7.x/pypy/translator/llvm/opaquenode.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/opaquenode.py pypy/release/0.7.x/pypy/translator/llvm/opwriter.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/opwriter.py pypy/release/0.7.x/pypy/translator/llvm/pyxwrapper.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/pyxwrapper.py pypy/release/0.7.x/pypy/translator/llvm/structnode.py - copied, changed from r16650, pypy/release/0.7.x/pypy/translator/llvm2/structnode.py pypy/release/0.7.x/pypy/translator/llvm/test/ - copied from r16650, pypy/release/0.7.x/pypy/translator/llvm2/test/ pypy/release/0.7.x/pypy/translator/llvm/tool/ - copied from r16650, pypy/release/0.7.x/pypy/translator/llvm2/tool/ pypy/release/0.7.x/pypy/translator/llvm/varsize.py - copied unchanged from r16650, pypy/release/0.7.x/pypy/translator/llvm2/varsize.py Removed: pypy/release/0.7.x/pypy/translator/llvm2/ Modified: pypy/release/0.7.x/pypy/translator/llvm/demo/bpnn.py pypy/release/0.7.x/pypy/translator/llvm/demo/richards.py pypy/release/0.7.x/pypy/translator/llvm/demo/run.py pypy/release/0.7.x/pypy/translator/llvm/test/test_class.py pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py pypy/release/0.7.x/pypy/translator/llvm/test/test_exception.py pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm.py pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py pypy/release/0.7.x/pypy/translator/llvm/test/test_lltype.py pypy/release/0.7.x/pypy/translator/llvm/test/test_seq.py pypy/release/0.7.x/pypy/translator/llvm/test/test_snippet.py pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py pypy/release/0.7.x/pypy/translator/llvm/tool/suggested_primitive.py pypy/release/0.7.x/pypy/translator/test/test_backendoptimization.py pypy/release/0.7.x/pypy/translator/translator.py Log: Rename llvm2 to llvm. Modified: pypy/release/0.7.x/pypy/translator/llvm/demo/bpnn.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/demo/bpnn.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/demo/bpnn.py Fri Aug 26 17:52:10 2005 @@ -211,7 +211,7 @@ return 0 #_________________________________________________________ -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm.genllvm import compile_function import py def test_demo(): @@ -245,5 +245,5 @@ return 0 if __name__ == "__main__": - from pypy.translator.llvm2.demo.run import run + from pypy.translator.llvm.demo.run import run run(main_noargs, "bpnn") Modified: pypy/release/0.7.x/pypy/translator/llvm/demo/richards.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/demo/richards.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/demo/richards.py Fri Aug 26 17:52:10 2005 @@ -422,5 +422,5 @@ if __name__ == "__main__": import autopath - from pypy.translator.llvm2.demo.run import run + from pypy.translator.llvm.demo.run import run run(main_noargs, "richards") Modified: pypy/release/0.7.x/pypy/translator/llvm/demo/run.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/demo/run.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/demo/run.py Fri Aug 26 17:52:10 2005 @@ -2,7 +2,7 @@ import os import sys -from pypy.translator.llvm2.genllvm import compile_module +from pypy.translator.llvm.genllvm import compile_module from pypy.translator.translator import Translator def p(): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_class.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_class.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_class.py Fri Aug 26 17:52:10 2005 @@ -3,8 +3,8 @@ from pypy.translator.translator import Translator from pypy.objspace.flow.model import Constant, Variable -from pypy.translator.llvm2.genllvm import compile_function -from pypy.translator.llvm2.test import llvmsnippet +from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test import llvmsnippet #py.log.setconsumer("genllvm", py.log.STDOUT) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_exc_operation.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py Fri Aug 26 17:52:10 2005 @@ -1,6 +1,6 @@ import py import sys -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm.genllvm import compile_function from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift def test_zerodiv_int(): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_exception.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_exception.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_exception.py Fri Aug 26 17:52:10 2005 @@ -1,6 +1,6 @@ import py -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm.genllvm import compile_function from pypy.translator.test.snippet import try_raise_choose from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py Fri Aug 26 17:52:10 2005 @@ -5,7 +5,7 @@ import py from pypy.tool.udir import udir -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm.genllvm import compile_function from pypy.rpython.rarithmetic import r_uint py.log.setconsumer("genllvm", py.log.STDOUT) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_gc.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py Fri Aug 26 17:52:10 2005 @@ -1,8 +1,8 @@ import sys import py -from pypy.translator.llvm2.genllvm import use_boehm_gc -from pypy.translator.llvm2.genllvm import compile_module_function +from pypy.translator.llvm.genllvm import use_boehm_gc +from pypy.translator.llvm.genllvm import compile_module_function py.log.setconsumer("genllvm", py.log.STDOUT) py.log.setconsumer("genllvm database prepare", None) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm.py Fri Aug 26 17:52:10 2005 @@ -4,7 +4,7 @@ import py from pypy.rpython.rarithmetic import r_uint -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm.genllvm import compile_function py.log.setconsumer("genllvm", py.log.STDOUT) py.log.setconsumer("genllvm database prepare", None) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_genllvm1.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py Fri Aug 26 17:52:10 2005 @@ -5,8 +5,8 @@ from pypy.translator.translator import Translator from pypy.objspace.flow.model import Constant, Variable -from pypy.translator.llvm2.genllvm import compile_function -from pypy.translator.llvm2.test import llvmsnippet +from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test import llvmsnippet class TestGenLLVM(object): def test_simple1(self): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_lltype.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_lltype.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_lltype.py Fri Aug 26 17:52:10 2005 @@ -3,8 +3,8 @@ from pypy.rpython import lltype -from pypy.translator.llvm2.genllvm import compile_function -from pypy.translator.llvm2 import database, codewriter +from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm import database, codewriter from pypy.rpython import rarithmetic py.log.setconsumer("genllvm", py.log.STDOUT) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_seq.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_seq.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_seq.py Fri Aug 26 17:52:10 2005 @@ -3,8 +3,8 @@ from pypy.translator.translator import Translator from pypy.objspace.flow.model import Constant, Variable -from pypy.translator.llvm2.genllvm import compile_function -from pypy.translator.llvm2.test import llvmsnippet +from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test import llvmsnippet class TestLLVMArray(object): def test_array(self): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_snippet.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_snippet.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_snippet.py Fri Aug 26 17:52:10 2005 @@ -1,6 +1,6 @@ from __future__ import division -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm.genllvm import compile_function from pypy.translator.test import snippet as test class TestSnippet(object): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/test/test_typed.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py Fri Aug 26 17:52:10 2005 @@ -4,7 +4,7 @@ from pypy.translator.test import snippet from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift -from pypy.translator.llvm2.genllvm import compile_function +from pypy.translator.llvm.genllvm import compile_function def test_call_five(): def wrapper(): Modified: pypy/release/0.7.x/pypy/translator/llvm/tool/suggested_primitive.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm2/tool/suggested_primitive.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/tool/suggested_primitive.py Fri Aug 26 17:52:10 2005 @@ -4,7 +4,7 @@ from sets import Set from pypy.rpython.module import ll_os #XXX keep up to date -from pypy.translator.llvm2.module.extfunction import extfunctions +from pypy.translator.llvm.module.extfunction import extfunctions def main(): seen = Set() Modified: pypy/release/0.7.x/pypy/translator/test/test_backendoptimization.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/test/test_backendoptimization.py (original) +++ pypy/release/0.7.x/pypy/translator/test/test_backendoptimization.py Fri Aug 26 17:52:10 2005 @@ -4,7 +4,7 @@ from pypy.rpython.llinterp import LLInterpreter from pypy.objspace.flow.model import checkgraph from pypy.translator.test.snippet import simple_method -from pypy.translator.llvm2.log import log +from pypy.translator.llvm.log import log import py log = py.log.Producer('test_backendoptimization') Modified: pypy/release/0.7.x/pypy/translator/translator.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/translator.py (original) +++ pypy/release/0.7.x/pypy/translator/translator.py Fri Aug 26 17:52:10 2005 @@ -199,7 +199,7 @@ Returns LLVM translation. """ - from pypy.translator.llvm2 import genllvm + from pypy.translator.llvm import genllvm if self.annotator is None: raise ValueError, "function has to be annotated." gen = genllvm.GenLLVM(self) @@ -280,7 +280,7 @@ Returns LLVM translation with or without optimization. """ - from pypy.translator.llvm2 import genllvm + from pypy.translator.llvm import genllvm if self.annotator is None: raise ValueError, "function has to be annotated." if standalone: From hpk at codespeak.net Fri Aug 26 17:52:27 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 17:52:27 +0200 (CEST) Subject: [pypy-svn] r16652 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826155227.475F927B6D@code1.codespeak.net> Author: hpk Date: Fri Aug 26 17:52:26 2005 New Revision: 16652 Modified: pypy/release/0.7.x/pypy/doc/faq.txt Log: issue102 testing wrote a RPython FAQ entry and modified the one on why PyPy is slow. Modified: pypy/release/0.7.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/faq.txt (original) +++ pypy/release/0.7.x/pypy/doc/faq.txt Fri Aug 26 17:52:26 2005 @@ -12,9 +12,21 @@ PyPy so slow? - Why is PyPy so slow? +Why is PyPy so slow? - Our translation process does not optimize the produced code very - much yet. Just one example: if you use a ``for i in range(x)`` loop - the loop will be ended by raising an exception (although the ``range`` - list will not be created in its entirety). \ No newline at end of file + Our translation process does not try to optimize the produced + code very much. So far the project has been focused on + getting a well tested very compliant self-contained PYthon + static implementation. During 2005 and 2006 we are targetting + optimizations at various levels. If you then still think + that PyPy is slow then we will have to find a better answer :-) + +What is RPython? + + RPython is the restricted subset of the Python language that + we are able to translate to machine level code. A major part of + PyPy's interpreter and type implementations is written + in this restricted style. For a more exhaustive definitions + please refer to `RPython`_. + +.. _`RPython`: coding-guide.html#rpython From ac at codespeak.net Fri Aug 26 17:59:23 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 26 Aug 2005 17:59:23 +0200 (CEST) Subject: [pypy-svn] r16654 - pypy/release/0.7.x/pypy/module/unicodedata Message-ID: <20050826155923.3A9E427B64@code1.codespeak.net> Author: ac Date: Fri Aug 26 17:59:23 2005 New Revision: 16654 Modified: pypy/release/0.7.x/pypy/module/unicodedata/LICENSE (props changed) Log: Fix eol-style From hpk at codespeak.net Fri Aug 26 18:01:50 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 18:01:50 +0200 (CEST) Subject: [pypy-svn] r16655 - pypy/release/0.7.x Message-ID: <20050826160150.CC39127B6D@code1.codespeak.net> Author: hpk Date: Fri Aug 26 18:01:50 2005 New Revision: 16655 Modified: pypy/release/0.7.x/LICENSE Log: Jonathan should be mentioned with the copyright holders because we are using some of his code or have modified some of his code (as far as i know which i don't fully do actually). Modified: pypy/release/0.7.x/LICENSE ============================================================================== --- pypy/release/0.7.x/LICENSE (original) +++ pypy/release/0.7.x/LICENSE Fri Aug 26 18:01:50 2005 @@ -54,6 +54,7 @@ Laura Creighton Marius Gedminas Niklaus Haldimann + Jonathan David Riehl Guido van Rossum Heinrich-Heine University, Germany From ericvrp at codespeak.net Fri Aug 26 18:04:47 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 26 Aug 2005 18:04:47 +0200 (CEST) Subject: [pypy-svn] r16656 - pypy/release/0.7.x/pypy/translator Message-ID: <20050826160447.DCB2027B6D@code1.codespeak.net> Author: ericvrp Date: Fri Aug 26 18:04:47 2005 New Revision: 16656 Modified: pypy/release/0.7.x/pypy/translator/translator.py Log: forgot to check this in Modified: pypy/release/0.7.x/pypy/translator/translator.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/translator.py (original) +++ pypy/release/0.7.x/pypy/translator/translator.py Fri Aug 26 18:04:47 2005 @@ -275,7 +275,7 @@ else: return genc.CExtModuleBuilder(self, gcpolicy=gcpolicy) - def llvmcompile(self, really_compile=True, standalone=False, optimize=True): + def llvmcompile(self, really_compile=True, standalone=False, optimize=True, exe_name=None): """llvmcompile(self, really_compile=True, standalone=False, optimize=True) -> LLVM translation Returns LLVM translation with or without optimization. @@ -284,7 +284,8 @@ if self.annotator is None: raise ValueError, "function has to be annotated." if standalone: - exe_name = self.entrypoint.__name__ + if not exe_name: + exe_name = self.entrypoint.__name__ else: exe_name = None self.frozen = True From cfbolz at codespeak.net Fri Aug 26 18:11:45 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 18:11:45 +0200 (CEST) Subject: [pypy-svn] r16657 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826161145.6D09527B6D@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 18:11:43 2005 New Revision: 16657 Modified: pypy/release/0.7.x/pypy/doc/_ref.txt pypy/release/0.7.x/pypy/doc/coding-guide.txt pypy/release/0.7.x/pypy/doc/index.txt pypy/release/0.7.x/pypy/doc/translation.txt Log: add a reference to the new external function call section to coding-guide. remove llvm2 references. Modified: pypy/release/0.7.x/pypy/doc/_ref.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/_ref.txt (original) +++ pypy/release/0.7.x/pypy/doc/_ref.txt Fri Aug 26 18:11:43 2005 @@ -50,5 +50,5 @@ .. _`pypy/translator/annrpython.py`: ../../pypy/translator/annrpython.py .. _`translator/c/`: ../../pypy/translator/c .. _`translator/java/`: ../../pypy/translator/java -.. _`translator/llvm2/`: ../../pypy/translator/llvm2 +.. _`translator/llvm/`: ../../pypy/translator/llvm .. _`translator/tool/`: ../../pypy/translator/tool \ No newline at end of file Modified: pypy/release/0.7.x/pypy/doc/coding-guide.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/coding-guide.txt (original) +++ pypy/release/0.7.x/pypy/doc/coding-guide.txt Fri Aug 26 18:11:43 2005 @@ -634,6 +634,11 @@ Only specified names will be exported to a Mixed Module's applevel namespace. +Sometimes it is neccessary to really write some functions in C (or whatever +target language). See the `external functions documentation`_ for details. + +.. _`external functions documentation`: translation.html#extfunccalls + application level definitions ............................. Modified: pypy/release/0.7.x/pypy/doc/index.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/index.txt (original) +++ pypy/release/0.7.x/pypy/doc/index.txt Fri Aug 26 18:11:43 2005 @@ -113,7 +113,7 @@ `translator/java/`_ experimental code to utilize Java for annotation -`translator/llvm2/`_ contains the `LLVM backend`_ producing LLVM assembler +`translator/llvm/`_ contains the `LLVM backend`_ producing LLVM assembler from fully annotated RPython programs `translator/tool/`_ helper tools for translation Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Fri Aug 26 18:11:43 2005 @@ -1170,9 +1170,7 @@ XXX to be added later - -.. include:: _ref.txt - +.. _extfunccalls: External Function Calls ======================= @@ -1362,4 +1360,7 @@ .. _`mixed posix module`: ../module/posix/ .. _`pypy/rpython/module/ll_os.py`: ../rpython/module/ll_os.py -.. _`pypy/translator/c/src/ll_os.h`: ../translator/c/src/ll_os.h \ No newline at end of file +.. _`pypy/translator/c/src/ll_os.h`: ../translator/c/src/ll_os.h + + +.. include:: _ref.txt From nik at codespeak.net Fri Aug 26 18:13:50 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 18:13:50 +0200 (CEST) Subject: [pypy-svn] r16658 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050826161350.13F5C27B6D@code1.codespeak.net> Author: nik Date: Fri Aug 26 18:13:48 2005 New Revision: 16658 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: moved op_repeat/op_max_until to interp-level. horrible spaghetti code but there is not much room for improvement ... Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 26 18:13:48 2005 @@ -454,71 +454,6 @@ self.executing_contexts[id(context)] = generator return has_finished - def op_repeat(self, ctx): - # create repeat context. all the hard work is done by the UNTIL - # operator (MAX_UNTIL, MIN_UNTIL) - # <1=min> <2=max> item tail - #self._log(ctx, "REPEAT", ctx.peek_code(2), ctx.peek_code(3)) - repeat = _sre._RepeatContext(ctx) - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(ctx.peek_code(1) + 1) - yield False - ctx.state.repeat = repeat.previous - ctx.has_matched = child_context.has_matched - yield True - - def op_max_until(self, ctx): - # maximizing repeat - # <1=min> <2=max> item tail - repeat = ctx.state.repeat - if repeat is None: - raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") - mincount = repeat.peek_code(2) - maxcount = repeat.peek_code(3) - ctx.state.string_position = ctx.string_position - count = repeat.count + 1 - #self._log(ctx, "MAX_UNTIL", count) - - if count < mincount: - # not enough matches - repeat.count = count - child_context = repeat.push_new_context(4) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - yield True - - if (count < maxcount or maxcount == MAXREPEAT) \ - and ctx.state.string_position != repeat.last_position: - # we may have enough matches, if we can match another item, do so - repeat.count = count - ctx.state.marks_push() - save_last_position = repeat.last_position # zero-width match protection - repeat.last_position = ctx.state.string_position - child_context = repeat.push_new_context(4) - yield False - repeat.last_position = save_last_position - if child_context.has_matched == MATCHED: - ctx.state.marks_pop_discard() - ctx.has_matched = MATCHED - yield True - ctx.state.marks_pop() - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - - # cannot match more repeated items here. make sure the tail matches - ctx.state.repeat = repeat.previous - child_context = ctx.push_new_context(1) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - yield True - def op_min_until(self, ctx): # minimizing repeat # <1=min> <2=max> item tail @@ -571,34 +506,6 @@ #self._log(ctx, "UNKNOWN", ctx.peek_code()) raise RuntimeError("Internal re error. Unknown opcode: %s" % ctx.peek_code()) - def count_repetitions(self, ctx, maxcount): - """Returns the number of repetitions of a single item, starting from the - current string position. The code pointer is expected to point to a - REPEAT_ONE operation (with the repeated 4 ahead).""" - count = 0 - real_maxcount = ctx.state.end - ctx.string_position - if maxcount < real_maxcount and maxcount != MAXREPEAT: - real_maxcount = maxcount - # XXX could special case every single character pattern here, as in C. - # This is a general solution, a bit hackisch, but works and should be - # efficient. - code_position = ctx.code_position - string_position = ctx.string_position - ctx.skip_code(4) - reset_position = ctx.code_position - while count < real_maxcount: - # this works because the single character pattern is followed by - # a success opcode - ctx.code_position = reset_position - self.dispatch(ctx.peek_code(), ctx) - if ctx.has_matched == NOT_MATCHED: # could be None as well - break - count += 1 - ctx.has_matched = UNDECIDED - ctx.code_position = code_position - ctx.string_position = string_position - return count - def _log(self, context, opname, *args): arg_string = ("%s " * len(args)) % args _log("|%s|%s|%s %s" % (context.pattern_codes, Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 18:13:48 2005 @@ -58,7 +58,7 @@ self.lastindex = -1 self.marks_stack = [] self.context_stack = [] - self.w_repeat = self.space.w_None + self.repeat = None def set_mark(self, mark_nr, position): if mark_nr & 1: @@ -262,24 +262,17 @@ at_end = interp2app(W_MatchContext.w_at_end), ) -def make_repeat_context(space, w_context): - # XXX Uhm, temporary - return space.wrap(W_RepeatContext(space, w_context)) class W_RepeatContext(W_MatchContext): - def __init__(self, space, w_context): - W_MatchContext.__init__(self, space, w_context.state, - space.newlist(w_context.pattern_codes_w[w_context.code_position:])) - self.w_count = space.wrap(-1) - self.w_previous = w_context.state.w_repeat - self.w_last_position = space.w_None - -W_RepeatContext.typedef = TypeDef("W_RepeatContext", W_MatchContext.typedef, - count = interp_attrproperty_obj_w("w_count", W_RepeatContext), - previous = interp_attrproperty_obj_w("w_previous", W_RepeatContext), - last_position = interp_attrproperty_obj_w("w_last_position", W_RepeatContext), -) + def __init__(self, space, context): + W_MatchContext.__init__(self, space, context.state, + space.newlist(context.pattern_codes_w[context.code_position:])) + self.count = -1 + self.previous = context.state.repeat + self.last_position = -1 + self.repeat_stack = [] + #### Main opcode dispatch loop @@ -587,6 +580,121 @@ ctx.has_matched = ctx.NOT_MATCHED return True +def op_repeat(space, ctx): + # create repeat context. all the hard work is done by the UNTIL + # operator (MAX_UNTIL, MIN_UNTIL) + # <1=min> <2=max> item tail + if not ctx.is_resumed(): + ctx.repeat = W_RepeatContext(space, ctx) + ctx.state.repeat = ctx.repeat + ctx.state.string_position = ctx.string_position + ctx.push_new_context(ctx.peek_code(1) + 1) + return False + else: + ctx.state.repeat = ctx.repeat + ctx.has_matched = ctx.child_context.has_matched + return True + +def op_max_until(space, ctx): + # maximizing repeat + # <1=min> <2=max> item tail + + # Case 1: First entry point + if not ctx.is_resumed(): + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + if count < mincount: + # not enough matches + repeat.count = count + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(0) #?Dummy for last_position + ctx.backup_value(0) + ctx.repeat = repeat + return False + if (count < maxcount or maxcount == MAXREPEAT) \ + and ctx.state.string_position != repeat.last_position: + # we may have enough matches, if we can match another item, do so + repeat.count = count + ctx.state.marks_push() + repeat.last_position = ctx.state.string_position + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(repeat.last_position) # zero-width match protection + ctx.backup_value(0) + ctx.repeat = repeat + return False + + # Cannot match more repeated items here. Make sure the tail matches. + ctx.state.repeat = repeat.previous + ctx.push_new_context(1) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(repeat.last_position) # zero-width match protection + ctx.backup_value(1) # tail matching + ctx.repeat = repeat + return False + + # Case 2: Resumed + else: + repeat = ctx.repeat + if repeat.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + values = ctx.restore_values() + mincount = values[0] + maxcount = values[1] + count = values[2] + save_last_position = values[3] + tail_matching = values[4] + + if tail_matching == 0: + if count < mincount: + ctx.has_matched = repeat.repeat_stack.pop().has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + return True + if count < maxcount or maxcount == MAXREPEAT: + # XXX can we really omit this test? + #and ctx.state.string_position != repeat.last_position: + repeat.last_position = save_last_position + if repeat.repeat_stack.pop().has_matched == ctx.MATCHED: + ctx.state.marks_pop_discard() + ctx.has_matched = ctx.MATCHED + return True + ctx.state.marks_pop() + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + + # Cannot match more repeated items here. Make sure the tail matches. + ctx.state.repeat = repeat.previous + ctx.push_new_context(1) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(repeat.last_position) # zero-width match protection + ctx.backup_value(1) # tail matching + return False + + else: # resuming after tail matching + ctx.has_matched = ctx.child_context.has_matched + repeat.has_matched = ctx.has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + return True + def op_jump(space, ctx): # jump forward # / @@ -713,12 +821,12 @@ op_jump, op_jump, op_literal, op_literal_ignore, op_mark, - None, #MAX_UNTIL, + op_max_until, None, #MIN_UNTIL, op_not_literal, op_not_literal_ignore, None, #NEGATE, None, #RANGE, - None, #REPEAT, + op_repeat, op_repeat_one, None, #SUBPATTERN, op_min_repeat_one, Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Fri Aug 26 18:13:48 2005 @@ -835,7 +835,7 @@ s.assert_no_match(opcodes, ["b"]) assert "aab" == s.search(opcodes, "aabb").group(0) - def test_max_until_error(self): + def test_min_until_error(self): opcodes = [s.OPCODES["min_until"], s.OPCODES["success"]] raises(RuntimeError, s.search, opcodes, "a") From ericvrp at codespeak.net Fri Aug 26 18:17:29 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 26 Aug 2005 18:17:29 +0200 (CEST) Subject: [pypy-svn] r16659 - pypy/release/0.7.x/pypy/translator/llvm/module Message-ID: <20050826161729.0A26827B6D@code1.codespeak.net> Author: ericvrp Date: Fri Aug 26 18:17:28 2005 New Revision: 16659 Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py Log: XXX we should get rid of this hardcoded .2 Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/support.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/support.py Fri Aug 26 18:17:28 2005 @@ -342,7 +342,7 @@ extfunctions["%main"] = [(), """ int %main(int %argc, sbyte** %argv) { entry: - %pypy_argv = call fastcc %RPyListOfString* %pypy_ll_newlist__listPtrConst_Signed(int 0) + %pypy_argv = call fastcc %RPyListOfString* %pypy_ll_newlist__listPtrConst_Signed.2(int 0) br label %no_exit no_exit: From rxe at codespeak.net Fri Aug 26 18:39:07 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 26 Aug 2005 18:39:07 +0200 (CEST) Subject: [pypy-svn] r16660 - pypy/release/0.7.x/pypy/translator/llvm Message-ID: <20050826163907.13AC527B66@code1.codespeak.net> Author: rxe Date: Fri Aug 26 18:39:06 2005 New Revision: 16660 Modified: pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py pypy/release/0.7.x/pypy/translator/llvm/funcnode.py pypy/release/0.7.x/pypy/translator/llvm/node.py pypy/release/0.7.x/pypy/translator/llvm/structnode.py Log: Remove some redundant properties as a first stage in optimising the generating of backend code. Modified: pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py Fri Aug 26 18:39:06 2005 @@ -9,7 +9,7 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = "%pypy_" + value._callable.__name__ + self.ref = self.make_ref("%pypy_", value._callable.__name__) def getdecl(self): T = self.value._TYPE Modified: pypy/release/0.7.x/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/funcnode.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/funcnode.py Fri Aug 26 18:39:06 2005 @@ -32,7 +32,7 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = self.make_ref('%', 'pypy_' + value.graph.name) + self.ref = self.make_ref('%pypy_', value.graph.name) self.graph = value.graph remove_same_as(self.graph) remove_double_links(self.db._translator, self.graph) Modified: pypy/release/0.7.x/pypy/translator/llvm/node.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/node.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/node.py Fri Aug 26 18:39:06 2005 @@ -4,6 +4,10 @@ nodename_count = {} def make_name(self, name): + " helper for creating names" + if " " in name or "<" in name: + name = '"%s"' % name + if name in self.nodename_count: postfix = '.%d' % self.nodename_count[name] self.nodename_count[name] += 1 @@ -15,32 +19,6 @@ def make_ref(self, prefix, name): return self.make_name(prefix + name) - def ref(): - def _get_ref(self): - return self._ref - def _set_ref(self, ref): - if hasattr(self, "_ref"): - raise TypeError, ("can only set ref once! currently: %s" % - (self._ref,)) - if " " in ref or "<" in ref: - ref = '"%s"' % (ref,) - self._ref = ref - return property(_get_ref, _set_ref) - ref = ref() - - def constructor_ref(): - def _get_ref(self): - return self._constructor_ref - def _set_ref(self, ref): - if hasattr(self, "_constructor_ref"): - raise TypeError, ("can only set constructor_ref once!" - " currently: %s" % (self._constructor_ref,)) - if " " in ref or "<" in ref: - ref = '"%s"' % (ref,) - self._constructor_ref = ref - return property(_get_ref, _set_ref) - constructor_ref = constructor_ref() - def setup(self): pass Modified: pypy/release/0.7.x/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/structnode.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/structnode.py Fri Aug 26 18:39:06 2005 @@ -48,7 +48,8 @@ def __init__(self, db, struct): super(StructVarsizeTypeNode, self).__init__(db, struct) - self.constructor_ref = "%%new.varsizestruct.%s" % (self.name) + prefix = '%new.varsizestruct.' + self.constructor_ref = self.make_ref(prefix, self.name) self.constructor_decl = "%s * %s(%s %%len)" % \ (self.ref, self.constructor_ref, From pedronis at codespeak.net Fri Aug 26 18:42:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 18:42:28 +0200 (CEST) Subject: [pypy-svn] r16662 - in pypy/release/0.7.x/pypy/translator/c: . src Message-ID: <20050826164228.7A6EE27B66@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 18:42:26 2005 New Revision: 16662 Modified: pypy/release/0.7.x/pypy/translator/c/extfunc.py pypy/release/0.7.x/pypy/translator/c/src/main.h Log: prefix some dangerous helpers with _ and add a comment to why they are risky to use. Modified: pypy/release/0.7.x/pypy/translator/c/extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/extfunc.py Fri Aug 26 18:42:26 2005 @@ -75,12 +75,19 @@ def RPyString_New(length=lltype.Signed): return lltype.malloc(STR, length) + # !!! + # be extremely careful passing a gc tracked object + # from such an helper result to another one + # as argument, this could result in leaks + # Such result should be only from C code + # returned directly as results + p = lltype.Ptr(rlist.LIST_OF_STR) - def RPyListOfString_New(length=lltype.Signed): + def _RPyListOfString_New(length=lltype.Signed): return rlist.ll_newlist(p, length) - def RPyListOfString_SetItem(l=p, + def _RPyListOfString_SetItem(l=p, index=lltype.Signed, newstring=lltype.Ptr(STR)): rlist.ll_setitem_nonneg(l, index, newstring) Modified: pypy/release/0.7.x/pypy/translator/c/src/main.h ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/src/main.h (original) +++ pypy/release/0.7.x/pypy/translator/c/src/main.h Fri Aug 26 18:42:26 2005 @@ -12,12 +12,12 @@ errmsg = RPython_StartupCode(); if (errmsg) goto error; - list = RPyListOfString_New(argc); + list = _RPyListOfString_New(argc); if (RPyExceptionOccurred()) goto error; for (i=0; i Author: hpk Date: Fri Aug 26 18:46:26 2005 New Revision: 16663 Modified: pypy/release/0.7.x/pypy/doc/faq.txt Log: typo/formatting Modified: pypy/release/0.7.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/faq.txt (original) +++ pypy/release/0.7.x/pypy/doc/faq.txt Fri Aug 26 18:46:26 2005 @@ -14,12 +14,12 @@ Why is PyPy so slow? - Our translation process does not try to optimize the produced - code very much. So far the project has been focused on - getting a well tested very compliant self-contained PYthon - static implementation. During 2005 and 2006 we are targetting - optimizations at various levels. If you then still think - that PyPy is slow then we will have to find a better answer :-) + Our translation process does not try to optimize the produced code + very much. So far the project has been focused on getting a well + tested very compliant self-contained static Python implementation. + During end 2005 and 2006 we are targetting optimizations at various + levels. If you then still think that PyPy is slow then we will + have to find a better answer :-) What is RPython? From arigo at codespeak.net Fri Aug 26 18:51:38 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 18:51:38 +0200 (CEST) Subject: [pypy-svn] r16664 - pypy/release/0.7.x/lib-python/modified-2.4.1/test Message-ID: <20050826165138.8A94627B68@code1.codespeak.net> Author: arigo Date: Fri Aug 26 18:51:35 2005 New Revision: 16664 Modified: pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_copy.py Log: Removed RuntimeError checks that have nothing to do here any more. If necessary, added some structure checks instead. Modified: pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_copy.py ============================================================================== --- pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_copy.py (original) +++ pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_copy.py Fri Aug 26 18:51:35 2005 @@ -374,7 +374,6 @@ x = [] x.append(x) y = copy.deepcopy(x) - self.assertRaises(RuntimeError, cmp, y, x) self.assert_(y is not x) self.assert_(y[0] is y) self.assertEqual(len(y), 1) @@ -390,9 +389,11 @@ x = ([],) x[0].append(x) y = copy.deepcopy(x) - self.assertRaises(RuntimeError, cmp, y, x) self.assert_(y is not x) - self.assert_(y[0] is not x[0]) + self.assertEqual(type(y), tuple) + self.assertEqual(len(y), 1) + self.assertEqual(type(y[0]), list) + self.assertEqual(len(y[0]), 1) self.assert_(y[0][0] is y) def test_deepcopy_dict(self): @@ -406,7 +407,6 @@ x = {} x['foo'] = x y = copy.deepcopy(x) - self.assertRaises(RuntimeError, cmp, y, x) self.assert_(y is not x) self.assert_(y['foo'] is y) self.assertEqual(len(y), 1) From pedronis at codespeak.net Fri Aug 26 18:59:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 18:59:59 +0200 (CEST) Subject: [pypy-svn] r16666 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826165959.2439427B66@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 18:59:57 2005 New Revision: 16666 Modified: pypy/release/0.7.x/pypy/doc/translation.txt Log: fix typo Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Fri Aug 26 18:59:57 2005 @@ -1258,7 +1258,7 @@ changed. This function is a generator that yields tuples of the form ``('c_name', LLTYPE)``. This makes the genc assign the name ``c_name`` to the type ``LLTYPE``. Similarly all the function defined in -``predeclare_utility_functions`` are automacially made accessible under their +``predeclare_utility_functions`` are automatically made accessible under their name in C. .. _`pypy/translator/c/extfunc.py`: ../translator/c/extfunc.py From nik at codespeak.net Fri Aug 26 19:01:45 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 19:01:45 +0200 (CEST) Subject: [pypy-svn] r16667 - pypy/dist/pypy/module/_sre Message-ID: <20050826170145.80EE327B64@code1.codespeak.net> Author: nik Date: Fri Aug 26 19:01:41 2005 New Revision: 16667 Modified: pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: moved op_min_until to interp-level. core regex interpretation is now fully at interp-level! refactorings to be done next ... Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 26 19:01:41 2005 @@ -185,7 +185,7 @@ return match def match(self): - return self._match_search(match) + return self._match_search(_sre._match) def search(self): return self._match_search(search) @@ -394,126 +394,6 @@ return has_matched == MATCHED -class _Dispatcher(object): - - DISPATCH_TABLE = None - - def dispatch(self, code, context): - method = self.DISPATCH_TABLE.get(code, self.__class__.unknown) - return method(self, context) - - def unknown(self, code, ctx): - raise NotImplementedError() - - def build_dispatch_table(cls, code_dict, method_prefix): - if cls.DISPATCH_TABLE is not None: - return - table = {} - for key, value in code_dict.items(): - if hasattr(cls, "%s%s" % (method_prefix, key)): - table[value] = getattr(cls, "%s%s" % (method_prefix, key)) - cls.DISPATCH_TABLE = table - - build_dispatch_table = classmethod(build_dispatch_table) - - -class _OpcodeDispatcher(_Dispatcher): - - def __init__(self): - self.executing_contexts = {} - - def match(self, context): - """Returns True if the current context matches, False if it doesn't and - None if matching is not finished, ie must be resumed after child - contexts have been matched.""" - while context.remaining_codes() > 0 and context.has_matched == UNDECIDED: - opcode = context.peek_code() - if not self.dispatch(opcode, context): - return UNDECIDED - if context.has_matched == UNDECIDED: - context.has_matched = NOT_MATCHED - return context.has_matched - - 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)] - has_finished = generator.next() - else: - if _sre._opcode_is_at_interplevel(opcode): - has_finished = _sre._opcode_dispatch(opcode, context) - else: - method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown) - has_finished = method(self, context) - if hasattr(has_finished, "next"): # avoid using the types module - generator = has_finished - has_finished = generator.next() - if not has_finished: - self.executing_contexts[id(context)] = generator - return has_finished - - def op_min_until(self, ctx): - # minimizing repeat - # <1=min> <2=max> item tail - repeat = ctx.state.repeat - if repeat is None: - raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") - mincount = repeat.peek_code(2) - maxcount = repeat.peek_code(3) - ctx.state.string_position = ctx.string_position - count = repeat.count + 1 - #self._log(ctx, "MIN_UNTIL", count) - - if count < mincount: - # not enough matches - repeat.count = count - child_context = repeat.push_new_context(4) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - yield True - - # see if the tail matches - ctx.state.marks_push() - ctx.state.repeat = repeat.previous - child_context = ctx.push_new_context(1) - yield False - if child_context.has_matched == MATCHED: - ctx.has_matched = MATCHED - yield True - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - ctx.state.marks_pop() - - # match more until tail matches - if count >= maxcount and maxcount != MAXREPEAT: - ctx.has_matched = NOT_MATCHED - yield True - repeat.count = count - child_context = repeat.push_new_context(4) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - yield True - - def unknown(self, ctx): - #self._log(ctx, "UNKNOWN", ctx.peek_code()) - raise RuntimeError("Internal re error. Unknown opcode: %s" % ctx.peek_code()) - - def _log(self, context, opname, *args): - arg_string = ("%s " * len(args)) % args - _log("|%s|%s|%s %s" % (context.pattern_codes, - context.string_position, opname, arg_string)) - -_OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") - - def _log(message): if 0: print message Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 19:01:41 2005 @@ -695,6 +695,93 @@ ctx.state.string_position = ctx.string_position return True +def op_min_until(space, ctx): + # minimizing repeat + # <1=min> <2=max> item tail + + # Case 1: First entry point + if not ctx.is_resumed(): + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + + if count < mincount: + # not enough matches + repeat.count = count + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(0) + ctx.repeat = repeat + return False + + # see if the tail matches + ctx.state.marks_push() + ctx.state.repeat = repeat.previous + ctx.push_new_context(1) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(1) + ctx.repeat = repeat + return False + + # Case 2: Resumed + else: + repeat = ctx.repeat + if repeat.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + values = ctx.restore_values() + mincount = values[0] + maxcount = values[1] + count = values[2] + matching_state = values[3] + + if count < mincount: + # not enough matches + ctx.has_matched = repeat.repeat_stack.pop().has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + return True + + if matching_state == 1: + # returning from tail matching + if ctx.child_context.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + ctx.state.marks_pop() + + if not matching_state == 2: + # match more until tail matches + if count >= maxcount and maxcount != MAXREPEAT: + ctx.has_matched = ctx.NOT_MATCHED + return True + repeat.count = count + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(2) + ctx.repeat = repeat + return False + + # Final return + ctx.has_matched = repeat.repeat_stack.pop().has_matched + repeat.has_matched = ctx.has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + return True + def op_jump(space, ctx): # jump forward # / @@ -822,7 +909,7 @@ op_literal, op_literal_ignore, op_mark, op_max_until, - None, #MIN_UNTIL, + op_min_until, op_not_literal, op_not_literal_ignore, None, #NEGATE, None, #RANGE, From rxe at codespeak.net Fri Aug 26 19:08:39 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 26 Aug 2005 19:08:39 +0200 (CEST) Subject: [pypy-svn] r16668 - in pypy/release/0.7.x/pypy/translator/llvm: module test Message-ID: <20050826170839.BF99B27B68@code1.codespeak.net> Author: rxe Date: Fri Aug 26 19:08:38 2005 New Revision: 16668 Modified: pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py Log: Added ll_os_rmdir ll_os_mkdir ll_os_chdir to externs. Modified: pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c Fri Aug 26 19:08:38 2005 @@ -385,9 +385,9 @@ double pypy_ll_strtod_parts_to_float(struct RPyString *sign, - struct RPyString *beforept, - struct RPyString *afterpt, - struct RPyString *exponent) + struct RPyString *beforept, + struct RPyString *afterpt, + struct RPyString *exponent) { char *fail_pos; struct lconv *locale_data; @@ -685,3 +685,24 @@ RPYTHON_RAISE_OSERROR(errno); } } + +void pypy_ll_os_chdir(struct RPyString * path) { + int error = chdir(RPyString_AsString(path)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} + +void pypy_ll_os_mkdir(struct RPyString * path, int mode) { + int error = mkdir(RPyString_AsString(path), mode); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} + +void pypy_ll_os_rmdir(struct RPyString * path) { + int error = rmdir(RPyString_AsString(path)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py Fri Aug 26 19:08:38 2005 @@ -254,4 +254,45 @@ for i, s in enumerate(as_string): assert f(i) +def test_os_unlink(): + tmpfile = str(udir.join('test_os_path_exists.TMP')) + def fn(): + os.unlink(tmpfile) + return 0 + f = compile_function(fn, []) + open(tmpfile, 'w').close() + fn() + assert not os.path.exists(tmpfile) + +def test_chdir(): + path = '..' + def does_stuff(): + os.chdir(path) + return 0 + f1 = compile_function(does_stuff, []) + curdir = os.getcwd() + try: + os.chdir() + except: pass # toplevel + def does_stuff2(): + os.chdir(curdir) + return 0 + f1 = compile_function(does_stuff2, []) + f1() + assert curdir == os.getcwd() + +def test_mkdir_rmdir(): + path = str(udir.join('test_mkdir_rmdir')) + def does_stuff(delete): + if delete: + os.rmdir(path) + else: + os.mkdir(path, 0777) + return 0 + f1 = compile_function(does_stuff, [bool]) + f1(False) + assert os.path.exists(path) and os.path.isdir(path) + f1(True) + assert not os.path.exists(path) + # end of tests taken from c backend From ale at codespeak.net Fri Aug 26 19:13:38 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 26 Aug 2005 19:13:38 +0200 (CEST) Subject: [pypy-svn] r16669 - in pypy/release/0.7.x/pypy: interpreter module/sys Message-ID: <20050826171338.D771C27B69@code1.codespeak.net> Author: ale Date: Fri Aug 26 19:13:35 2005 New Revision: 16669 Modified: pypy/release/0.7.x/pypy/interpreter/interactive.py pypy/release/0.7.x/pypy/module/sys/__init__.py Log: issue135 testing Changed the sys.version to 0.7.0beta. Added the information to the interactiive banner. The solution is bit brittle relying on a specific format of the version string. A pypy_version attribute of sys might be a better idea Modified: pypy/release/0.7.x/pypy/interpreter/interactive.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/interactive.py (original) +++ pypy/release/0.7.x/pypy/interpreter/interactive.py Fri Aug 26 19:13:35 2005 @@ -126,9 +126,11 @@ #banner = "Python %s in pypy\n%s / %s" % ( # sys.version, self.__class__.__name__, # self.space.__class__.__name__) + w_sys = self.space.sys + version = self.space.str_w(self.space.getattr(w_sys, self.space.wrap('version'))) elapsed = time.time() - self.space._starttime - banner = "PyPy in %s on top of Python %s (startupttime: %.2f secs)" % ( - self.space.__repr__(), sys.version.split()[0], elapsed) + banner = "PyPy %s in %s on top of Python %s (startupttime: %.2f secs)" % ( + version.split()[2],self.space.__repr__(), sys.version.split()[0], elapsed) code.InteractiveConsole.interact(self, banner) def raw_input(self, prompt=""): Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/sys/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/sys/__init__.py Fri Aug 26 19:13:35 2005 @@ -50,7 +50,7 @@ 'copyright' : 'space.wrap("MIT-License")', 'api_version' : 'space.wrap(1012)', 'version_info' : 'space.wrap((2,4,1, "alpha", 42))', - 'version' : 'space.wrap("2.4.1 (pypy1 build)")', + 'version' : 'space.wrap("2.4.1 (pypy 0.7.0beta build)")', 'hexversion' : 'space.wrap(0x020401a0)', 'ps1' : 'space.wrap(">>>> ")', 'ps2' : 'space.wrap(".... ")', From arigo at codespeak.net Fri Aug 26 19:13:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 19:13:44 +0200 (CEST) Subject: [pypy-svn] r16670 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826171344.2BE0C27B70@code1.codespeak.net> Author: arigo Date: Fri Aug 26 19:13:43 2005 New Revision: 16670 Modified: pypy/release/0.7.x/pypy/doc/faq.txt Log: Do I have to rewrite my programs in RPython? Modified: pypy/release/0.7.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/faq.txt (original) +++ pypy/release/0.7.x/pypy/doc/faq.txt Fri Aug 26 19:13:43 2005 @@ -29,4 +29,10 @@ in this restricted style. For a more exhaustive definitions please refer to `RPython`_. +Do I have to rewrite my programs in RPython? + + No. PyPy always runs your code in its own interpreter, which is + a full and compliant Python 2.4 interpreter. RPython is only + the language in which parts of PyPy itself are written. + .. _`RPython`: coding-guide.html#rpython From nik at codespeak.net Fri Aug 26 19:30:44 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 19:30:44 +0200 (CEST) Subject: [pypy-svn] r16671 - in pypy/dist/pypy/module/_sre: . test Message-ID: <20050826173044.69A0F27B68@code1.codespeak.net> Author: nik Date: Fri Aug 26 19:30:42 2005 New Revision: 16671 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_interp_sre.py Log: heavy refactoring, getting rid of as many wrapped objects on interp-level as possible and of superfluous code at app-level. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Fri Aug 26 19:30:42 2005 @@ -19,9 +19,5 @@ interpleveldefs = { 'getlower': 'interp_sre.getlower', '_State': 'interp_sre.make_state', - '_MatchContext': 'interp_sre.make_context', - '_RepeatContext': 'interp_sre.make_repeat_context', '_match': 'interp_sre.match', - '_opcode_dispatch': 'interp_sre.opcode_dispatch', - '_opcode_is_at_interplevel': 'interp_sre.opcode_is_at_interplevel', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 26 19:30:42 2005 @@ -369,30 +369,6 @@ string_position += 1 return False -# XXX temporary constants for MatchContext.has_matched -UNDECIDED = 0 -MATCHED = 1 -NOT_MATCHED = 2 - -def match(state, pattern_codes): - # Optimization: Check string length. pattern_codes[3] contains the - # minimum length for a string to possibly match. - if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: - if state.end - state.string_position < pattern_codes[3]: - #_log("reject (got %d chars, need %d)" - # % (state.end - state.string_position, pattern_codes[3])) - return False - - dispatcher = _OpcodeDispatcher() - state.context_stack.append(_sre._MatchContext(state, pattern_codes)) - has_matched = UNDECIDED - while len(state.context_stack) > 0: - context = state.context_stack[-1] - has_matched = dispatcher.match(context) - if has_matched != UNDECIDED: # don't pop if context isn't done - state.context_stack.pop() - return has_matched == MATCHED - def _log(message): if 0: Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 19:30:42 2005 @@ -28,11 +28,8 @@ #### Core classes -# XXX the wrapped/unwrapped semantics of the following classes are currently -# very confusing because they are still used at app-level. - def make_state(space, w_string, w_start, w_end, w_flags): - # XXX Uhm, temporary + # XXX maybe turn this into a __new__ method of W_State return space.wrap(W_State(space, w_string, w_start, w_end, w_flags)) class W_State(Wrappable): @@ -51,15 +48,29 @@ self.end = end self.pos = start self.flags = space.int_w(w_flags) - self.reset() + self.w_reset() - def reset(self): + def w_reset(self): self.marks = [] self.lastindex = -1 self.marks_stack = [] self.context_stack = [] self.repeat = None + def w_create_regs(self, w_group_count): + """Creates a tuple of index pairs representing matched groups, a format + that's convenient for SRE_Match.""" + regs = [self.space.newtuple([self.space.wrap(self.start), self.space.wrap(self.string_position)])] + for group in range(self.space.int_w(w_group_count)): + mark_index = 2 * group + if mark_index + 1 < len(self.marks): + regs.append(self.space.newtuple([self.space.wrap(self.marks[mark_index]), + self.space.wrap(self.marks[mark_index + 1])])) + else: + regs.append(self.space.newtuple([self.space.wrap(-1), + self.space.wrap(-1)])) + return self.space.newtuple(regs) + def set_mark(self, mark_nr, position): if mark_nr & 1: # This id marks the end of a group. @@ -75,20 +86,6 @@ else: return -1, -1 - def create_regs(self, w_group_count): - """Creates a tuple of index pairs representing matched groups, a format - that's convenient for SRE_Match.""" - regs = [self.space.newtuple([self.space.wrap(self.start), self.space.wrap(self.string_position)])] - for group in range(self.space.int_w(w_group_count)): - mark_index = 2 * group - if mark_index + 1 < len(self.marks): - regs.append(self.space.newtuple([self.space.wrap(self.marks[mark_index]), - self.space.wrap(self.marks[mark_index + 1])])) - else: - regs.append(self.space.newtuple([self.space.wrap(-1), - self.space.wrap(-1)])) - return self.space.newtuple(regs) - def marks_push(self): self.marks_stack.append((self.marks[:], self.lastindex)) @@ -104,9 +101,6 @@ def lower(self, char_ord): return self.space.int_w(self.w_lower(self.space.wrap(char_ord))) - def w_lower(self, w_char_ord): - return getlower(self.space, w_char_ord, self.space.wrap(self.flags)) - def interp_attrproperty_int(name, cls): "NOT_RPYTHON: initialization-time only" def fget(space, obj): @@ -115,12 +109,6 @@ setattr(obj, name, space.int_w(w_value)) return GetSetProperty(fget, fset, cls=cls) -def interp_attrproperty_list_w(name, cls): - "NOT_RPYTHON: initialization-time only" - def fget(space, obj): - return space.newlist(getattr(obj, name)) - return GetSetProperty(fget, cls=cls) - def interp_attrproperty_obj_w(name, cls): "NOT_RPYTHON: initialization-time only" def fget(space, obj): @@ -137,30 +125,21 @@ pos = interp_attrproperty("pos", W_State), lastindex = interp_attrproperty("lastindex", W_State), repeat = interp_attrproperty_obj_w("w_repeat", W_State), - reset = interp2app(W_State.reset), - create_regs = interp2app(W_State.create_regs), - marks_push = interp2app(W_State.marks_push), - marks_pop = interp2app(W_State.marks_pop), - marks_pop_keep = interp2app(W_State.marks_pop_keep), - marks_pop_discard = interp2app(W_State.marks_pop_discard), - lower = interp2app(W_State.w_lower), + reset = interp2app(W_State.w_reset), + create_regs = interp2app(W_State.w_create_regs), ) -def make_context(space, w_state, w_pattern_codes): - # XXX Uhm, temporary - return space.wrap(W_MatchContext(space, w_state, w_pattern_codes)) - -class W_MatchContext(Wrappable): +class MatchContext: UNDECIDED = 0 MATCHED = 1 NOT_MATCHED = 2 - def __init__(self, space, w_state, w_pattern_codes): + def __init__(self, space, state, pattern_codes): self.space = space - self.state = w_state - self.pattern_codes_w = space.unpackiterable(w_pattern_codes) - self.string_position = w_state.string_position + self.state = state + self.pattern_codes = pattern_codes + self.string_position = state.string_position self.code_position = 0 self.has_matched = self.UNDECIDED self.backup = [] @@ -170,12 +149,11 @@ """Creates a new child context of this context and pushes it on the stack. pattern_offset is the offset off the current code position to start interpreting from.""" - pattern_codes_w = self.pattern_codes_w[self.code_position + pattern_offset:] - w_child_context = self.space.wrap(W_MatchContext(self.space, self.state, - self.space.newlist(pattern_codes_w))) - self.state.context_stack.append(w_child_context) - self.child_context = w_child_context - return w_child_context + pattern_codes = self.pattern_codes[self.code_position + pattern_offset:] + child_context = MatchContext(self.space, self.state, pattern_codes) + self.state.context_stack.append(child_context) + self.child_context = child_context + return child_context def is_resumed(self): return self.resume_at_opcode > -1 @@ -188,42 +166,28 @@ self.backup = [] return values - def peek_char(self, w_peek=0): - # XXX temporary hack - if w_peek == 0: - w_peek = self.space.wrap(0) + def peek_char(self, peek=0): return self.space.getitem(self.state.w_string, - self.space.add(self.space.wrap(self.string_position), w_peek)) + self.space.wrap(self.string_position + peek)) def peek_char_ord(self, peek=0): - return self.space.int_w(self.space.ord(self.peek_char(self.space.wrap(peek)))) + # XXX this is not very nice + return self.space.int_w(self.space.ord(self.peek_char(peek))) def skip_char(self, skip_count): self.string_position = self.string_position + skip_count - def w_skip_char(self, w_skip_count): - self.skip_char(self.space.int_w(w_skip_count)) - def remaining_chars(self): return self.state.end - self.string_position - def w_remaining_chars(self): - return self.space.wrap(self.remaining_chars()) - def peek_code(self, peek=0): - return self.space.int_w(self.pattern_codes_w[self.code_position + peek]) - - def w_peek_code(self, w_peek=0): - return self.space.wrap(self.peek_code(self.space.int_w(w_peek))) + return self.pattern_codes[self.code_position + peek] def skip_code(self, skip_count): self.code_position = self.code_position + skip_count - def w_skip_code(self, w_skip_count): - self.skip_code(self.space.int_w(w_skip_count)) - def remaining_codes(self): - return self.space.wrap(len(self.pattern_codes_w) - self.code_position) + return len(self.pattern_codes) - self.code_position def at_beginning(self): return self.string_position == 0 @@ -231,9 +195,6 @@ def at_end(self): return self.string_position == self.state.end - def w_at_end(self): - return self.space.newbool(self.at_end()) - def at_linebreak(self): return not self.at_end() and is_linebreak(self.space, self.peek_char()) @@ -241,33 +202,17 @@ if self.at_beginning() and self.at_end(): return False that = not self.at_beginning() \ - and word_checker(self.space, self.peek_char(self.space.wrap(-1))) + and word_checker(self.space, self.peek_char(-1)) this = not self.at_end() \ and word_checker(self.space, self.peek_char()) return this != that -W_MatchContext.typedef = TypeDef("W_MatchContext", - state = interp_attrproperty_w("state", W_MatchContext), - string_position = interp_attrproperty_int("string_position", W_MatchContext), - pattern_codes = interp_attrproperty_list_w("pattern_codes_w", W_MatchContext), - code_position = interp_attrproperty_int("code_position", W_MatchContext), - has_matched = interp_attrproperty_int("has_matched", W_MatchContext), - #push_new_context = interp2app(W_MatchContext.push_new_context), - peek_char = interp2app(W_MatchContext.peek_char), - skip_char = interp2app(W_MatchContext.w_skip_char), - remaining_chars = interp2app(W_MatchContext.w_remaining_chars), - peek_code = interp2app(W_MatchContext.w_peek_code), - skip_code = interp2app(W_MatchContext.w_skip_code), - remaining_codes = interp2app(W_MatchContext.remaining_codes), - at_end = interp2app(W_MatchContext.w_at_end), -) - -class W_RepeatContext(W_MatchContext): +class RepeatContext(MatchContext): def __init__(self, space, context): - W_MatchContext.__init__(self, space, context.state, - space.newlist(context.pattern_codes_w[context.code_position:])) + MatchContext.__init__(self, space, context.state, + context.pattern_codes[context.code_position:]) self.count = -1 self.previous = context.state.repeat self.last_position = -1 @@ -284,8 +229,9 @@ # if state.end - state.string_position < pattern_codes[3]: # return False state = w_state - state.context_stack.append(W_MatchContext(space, state, w_pattern_codes)) - has_matched = W_MatchContext.UNDECIDED + pattern_codes = [space.int_w(code) for code in space.unpackiterable(w_pattern_codes)] + state.context_stack.append(MatchContext(space, state, pattern_codes)) + has_matched = MatchContext.UNDECIDED while len(state.context_stack) > 0: context = state.context_stack[-1] if context.has_matched == context.UNDECIDED: @@ -305,10 +251,10 @@ opcode = context.resume_at_opcode else: opcode = context.peek_code() - #try: - has_finished = opcode_dispatch_table[opcode](space, context) - #except IndexError: - # raise RuntimeError("Internal re error. Unknown opcode: %s" % opcode) + try: + has_finished = opcode_dispatch_table[opcode](space, context) + except IndexError: + raise RuntimeError("Internal re error. Unknown opcode: %s" % opcode) if not has_finished: context.resume_at_opcode = opcode return context.UNDECIDED @@ -317,19 +263,6 @@ context.has_matched = context.NOT_MATCHED return context.has_matched -def opcode_dispatch(space, w_opcode, w_context): - opcode = space.int_w(w_opcode) - if opcode >= len(opcode_dispatch_table): - return space.newbool(False) - return space.newbool(opcode_dispatch_table[opcode](space, w_context)) - -def opcode_is_at_interplevel(space, w_opcode): - opcode = space.int_w(w_opcode) - try: - return space.newbool(opcode_dispatch_table[opcode] is not None) - except IndexError: - return space.newbool(False) - def op_success(space, ctx): # end of pattern ctx.state.string_position = ctx.string_position @@ -425,7 +358,7 @@ return skip = ctx.peek_code(1) ctx.skip_code(2) # set op pointer to the set code - char_code = space.int_w(space.ord(ctx.peek_char())) + char_code = ctx.peek_char_ord() if ignore: char_code = ctx.state.lower(char_code) if not check_charset(space, char_code, ctx): @@ -585,7 +518,7 @@ # operator (MAX_UNTIL, MIN_UNTIL) # <1=min> <2=max> item tail if not ctx.is_resumed(): - ctx.repeat = W_RepeatContext(space, ctx) + ctx.repeat = RepeatContext(space, ctx) ctx.state.repeat = ctx.repeat ctx.state.string_position = ctx.string_position ctx.push_new_context(ctx.peek_code(1) + 1) @@ -615,7 +548,7 @@ ctx.backup_value(mincount) ctx.backup_value(maxcount) ctx.backup_value(count) - ctx.backup_value(0) #?Dummy for last_position + ctx.backup_value(0) # Dummy for last_position ctx.backup_value(0) ctx.repeat = repeat return False @@ -803,7 +736,7 @@ return True while group_start < group_end: # XXX This is really a bit unwieldy. Can this be improved? - new_char = space.int_w(space.ord(ctx.peek_char())) + new_char = ctx.peek_char_ord() old_char = space.int_w(space.ord( space.getitem(ctx.state.w_string, space.wrap(group_start)))) if ctx.at_end() or (not ignore and old_char != new_char) \ @@ -1019,7 +952,7 @@ return ctx.at_beginning() def at_beginning_line(space, ctx): - return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(space.wrap(-1))) + return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(-1)) def at_end(space, ctx): return ctx.at_end() or (ctx.remaining_chars() == 1 and ctx.at_linebreak()) Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Fri Aug 26 19:30:42 2005 @@ -11,7 +11,7 @@ state = isre.W_State(space, space.wrap(string), space.wrap(0), space.wrap(end), space.wrap(0)) state.string_position = string_position - return isre.W_MatchContext(space, state, space.newlist([])) + return isre.MatchContext(space, state, []) def test_is_uni_linebreak(space): for char in ["\n", "\r"]: From pedronis at codespeak.net Fri Aug 26 19:39:25 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 19:39:25 +0200 (CEST) Subject: [pypy-svn] r16672 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826173925.3D4F527B68@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 19:39:23 2005 New Revision: 16672 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: renamed the genc produced standalone executable to 'pypy-c'. To be tested... Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Fri Aug 26 19:39:23 2005 @@ -658,6 +658,10 @@ else: print 'Generating and compiling C code...' c_entry_point = t.ccompile(standalone=standalone, gcpolicy=gcpolicy) + if standalone: + p = py.path.local(c_entry_point) + p.rename('pypy-c') + c_entry_point = str(p.new(basename='pypy-c')) update_usession_dir() if not options['-o']: print 'Running!' From hpk at codespeak.net Fri Aug 26 19:59:58 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 19:59:58 +0200 (CEST) Subject: [pypy-svn] r16673 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826175958.AD7F827B68@code1.codespeak.net> Author: hpk Date: Fri Aug 26 19:59:58 2005 New Revision: 16673 Added: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt - copied, changed from r16670, pypy/release/0.7.x/pypy/doc/release-0.6.txt Log: issue122 in-progress a first go at a release-0.7.0 announcement. comemnts and suggestions welcome. i plan to work on it some more (possibly tomorrow morning). From jacob at codespeak.net Fri Aug 26 20:03:38 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Fri, 26 Aug 2005 20:03:38 +0200 (CEST) Subject: [pypy-svn] r16674 - pypy/dist/pypy/lib Message-ID: <20050826180338.D3C0627B69@code1.codespeak.net> Author: jacob Date: Fri Aug 26 20:03:36 2005 New Revision: 16674 Modified: pypy/dist/pypy/lib/binascii.py Log: Fixed minor problem with soft linebreaks in qp. Modified: pypy/dist/pypy/lib/binascii.py ============================================================================== --- pypy/dist/pypy/lib/binascii.py (original) +++ pypy/dist/pypy/lib/binascii.py Fri Aug 26 20:03:36 2005 @@ -255,10 +255,6 @@ istext=False means that \r and \n are treated as regular characters header=True encodes space characters with '_' and requires real '_' characters to be quoted. - - - The CPython does not encode newlines as CRLF sequences. This - seems to be non-standard, and we copy this behaviour. """ crlf = s.find('\r\n') lf = s.find('\n') @@ -278,8 +274,7 @@ lines = s.split('\n') - soft_lbr = '=\n' # The way CPython does it - #soft_lbr = '=\r\n' # The way I think the standard specifies + soft_lbr = '=' + linebreak result = [] for line in lines: charlist = [] From pedronis at codespeak.net Fri Aug 26 20:07:47 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 20:07:47 +0200 (CEST) Subject: [pypy-svn] r16675 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826180747.458B827B68@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 20:07:45 2005 New Revision: 16675 Added: pypy/release/0.7.x/pypy/translator/goal/targetnopstandalone.py - copied, changed from r16666, pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: oops, was broken Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Fri Aug 26 20:07:45 2005 @@ -658,10 +658,11 @@ else: print 'Generating and compiling C code...' c_entry_point = t.ccompile(standalone=standalone, gcpolicy=gcpolicy) - if standalone: + if standalone: # xxx fragile and messy + import py p = py.path.local(c_entry_point) p.rename('pypy-c') - c_entry_point = str(p.new(basename='pypy-c')) + c_entry_point = './pypy-c' update_usession_dir() if not options['-o']: print 'Running!' From pedronis at codespeak.net Fri Aug 26 20:08:22 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 20:08:22 +0200 (CEST) Subject: [pypy-svn] r16676 - in pypy/release/0.7.x/pypy/translator: c/test tool Message-ID: <20050826180822.B4BA027B68@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 20:08:21 2005 New Revision: 16676 Modified: pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py pypy/release/0.7.x/pypy/translator/tool/cbuild.py Log: try to skip test_boehm if boehm is not there Modified: pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py (original) +++ pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py Fri Aug 26 20:08:21 2005 @@ -50,6 +50,9 @@ def test_boehm(): import py + from pypy.translator.tool import cbuild + if not cbuild.check_boehm_presence(): + py.test.skip("no boehm gc on this machine") gw = py.execnet.PopenGateway() chan = gw.remote_exec(py.code.Source(test_src)) res = chan.receive() Modified: pypy/release/0.7.x/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/tool/cbuild.py (original) +++ pypy/release/0.7.x/pypy/translator/tool/cbuild.py Fri Aug 26 20:08:21 2005 @@ -261,3 +261,22 @@ extra_preargs=extra_preargs) return str(outputfilename) +def check_boehm_presence(): + from pypy.tool.udir import udir + try: + cfile = udir.join('check_boehm.c') + cfname = str(cfile) + cfile = cfile.open('w') + cfile.write(""" +#include + +int main() { + return 0; +} +""") + cfile.close() + build_executable([cfname], libraries=['gc']) + except: + return False + else: + return True From nik at codespeak.net Fri Aug 26 20:10:58 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 20:10:58 +0200 (CEST) Subject: [pypy-svn] r16678 - pypy/dist/pypy/module/_sre Message-ID: <20050826181058.20F4727B69@code1.codespeak.net> Author: nik Date: Fri Aug 26 20:10:56 2005 New Revision: 16678 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: refactored match and search functions at interp-level Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Fri Aug 26 20:10:56 2005 @@ -19,5 +19,6 @@ interpleveldefs = { 'getlower': 'interp_sre.getlower', '_State': 'interp_sre.make_state', - '_match': 'interp_sre.match', + '_match': 'interp_sre.w_match', + '_search': 'interp_sre.w_search', } Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 26 20:10:56 2005 @@ -47,7 +47,7 @@ instance. Return None if no position in the string matches the pattern.""" state = _sre._State(string, pos, endpos, self.flags) - if search(state, self._code): + if _sre._search(state, self._code): return SRE_Match(self, state) else: return None @@ -59,7 +59,7 @@ while state.start <= state.end: state.reset() state.string_position = state.start - if not search(state, self._code): + if not _sre._search(state, self._code): break match = SRE_Match(self, state) if self.groups == 0 or self.groups == 1: @@ -86,7 +86,7 @@ while not count or n < count: state.reset() state.string_position = state.start - if not search(state, self._code): + if not _sre._search(state, self._code): break if last_pos < state.start: sublist.append(string[last_pos:state.start]) @@ -132,7 +132,7 @@ while not maxsplit or n < maxsplit: state.reset() state.string_position = state.start - if not search(state, self._code): + if not _sre._search(state, self._code): break if state.start == state.string_position: # zero-width match if last == state.end: # or end of string @@ -188,7 +188,7 @@ return self._match_search(_sre._match) def search(self): - return self._match_search(search) + return self._match_search(_sre._search) class SRE_Match(object): @@ -291,48 +291,6 @@ raise TypeError, "cannot copy this pattern object" -def search(state, pattern_codes): - flags = 0 - if pattern_codes[0] == OPCODES["info"]: - # optimization info block - # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> - #if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: - # return state.fast_search(pattern_codes) - flags = pattern_codes[2] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] - - string_position = state.start - """ - if pattern_codes[0] == OPCODES["literal"]: - # Special case: Pattern starts with a literal character. This is - # used for short prefixes - character = pattern_codes[1] - while True: - while string_position < state.end \ - and ord(state.string[string_position]) != character: - string_position += 1 - if string_position >= state.end: - return False - state.start = string_position - string_position += 1 - state.string_position = string_position - if flags & SRE_INFO_LITERAL: - return True - if match(state, pattern_codes[2:]): - return True - return False - """ - - # General case - while string_position <= state.end: - state.reset() - state.start = state.string_position = string_position - if _sre._match(state, pattern_codes): - return True - string_position += 1 - return False - - def fast_search(state, pattern_codes): """Skips forward in a string as fast as possible using information from an optimization info block.""" Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 20:10:56 2005 @@ -11,8 +11,11 @@ #### Exposed functions # XXX can we import those safely from sre_constants? +SRE_INFO_LITERAL = 2 SRE_FLAG_LOCALE = 4 # honour system locale SRE_FLAG_UNICODE = 32 # use unicode locale +OPCODE_INFO = 17 +OPCODE_LITERAL = 19 MAXREPEAT = 65535 def getlower(space, w_char_ord, w_flags): @@ -99,7 +102,9 @@ self.marks_stack.pop() def lower(self, char_ord): - return self.space.int_w(self.w_lower(self.space.wrap(char_ord))) + # XXX this is ugly + space = self.space + return space.int_w(getlower(space, space.wrap(char_ord), space.wrap(self.flags))) def interp_attrproperty_int(name, cls): "NOT_RPYTHON: initialization-time only" @@ -221,15 +226,43 @@ #### Main opcode dispatch loop -def match(space, w_state, w_pattern_codes): +def w_search(space, w_state, w_pattern_codes): + pattern_codes = [space.int_w(code) for code + in space.unpackiterable(w_pattern_codes)] + return space.newbool(search(space, w_state, pattern_codes)) + +def search(space, state, pattern_codes): + flags = 0 + if pattern_codes[0] == OPCODE_INFO: + # optimization info block + # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> + # XXX fast_search temporarily disabled + #if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: + # return state.fast_search(pattern_codes) + flags = pattern_codes[2] + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + + string_position = state.start + while string_position <= state.end: + state.w_reset() + state.start = state.string_position = string_position + if match(space, state, pattern_codes): + return True + string_position += 1 + return False + +def w_match(space, w_state, w_pattern_codes): + pattern_codes = [space.int_w(code) for code + in space.unpackiterable(w_pattern_codes)] + return space.newbool(match(space, w_state, pattern_codes)) + +def match(space, state, pattern_codes): # Optimization: Check string length. pattern_codes[3] contains the # minimum length for a string to possibly match. # XXX disabled for now #if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: # if state.end - state.string_position < pattern_codes[3]: # return False - state = w_state - pattern_codes = [space.int_w(code) for code in space.unpackiterable(w_pattern_codes)] state.context_stack.append(MatchContext(space, state, pattern_codes)) has_matched = MatchContext.UNDECIDED while len(state.context_stack) > 0: @@ -240,7 +273,7 @@ has_matched = context.has_matched if has_matched != context.UNDECIDED: # don't pop if context isn't done state.context_stack.pop() - return space.newbool(has_matched == context.MATCHED) + return has_matched == context.MATCHED def dispatch_loop(space, context): """Returns MATCHED if the current context matches, NOT_MATCHED if it doesn't From arigo at codespeak.net Fri Aug 26 20:12:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 20:12:18 +0200 (CEST) Subject: [pypy-svn] r16679 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826181218.9223D27B69@code1.codespeak.net> Author: arigo Date: Fri Aug 26 20:12:16 2005 New Revision: 16679 Modified: pypy/release/0.7.x/pypy/doc/architecture.txt pypy/release/0.7.x/pypy/doc/faq.txt Log: Updates to the Status chapter of Architecture, and small additions wherever needed. Modified: pypy/release/0.7.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.7.x/pypy/doc/architecture.txt Fri Aug 26 20:12:16 2005 @@ -53,29 +53,31 @@ .. _Psyco: http://psyco.sourceforge.net .. _Stackless: http://stackless.com -Status of the implementation (May 2005) +Status of the implementation (Aug 2005) --------------------------------------- In a number of one week sprints, attracting approximately 10 developers each, -we made an almost complete implementation of Python in Python. Currently it is -slow, benchmarking at a factor 2000 times slower than regular Python -(henceforth referred to as CPython). This was expected because running a -bytecode interpreter on top of CPython obviously imposes a -double-interpretation penalty. - -Our rather complete and Python 2.3-compliant interpreter is about 22000 lines -of code, with another 7000 lines of unit tests. If we include the tools, the -parts related to code analysis and generation, and the standard library -modules ported from C, PyPy is now 55000 lines of code and 20000 lines of -tests. +we made an almost complete implementation of Python in Python. -PyPy already passes a lot of CPython's own regression tests, including 90% of the -core tests not depending on C extension modules (most of the remaining 10% are +Our rather complete and Python 2.4-compliant interpreter is about 30'000-50'000 +lines of code (depending on the way you count code borrowed and adapted from +other sources), with another 14'000 lines of unit tests. +If we include the tools, the parts related to code analysis and generation, +and the standard library modules ported from C, PyPy is now 105'000 lines of +code and 29'000 lines of tests. + +PyPy already passes a lot of CPython's own regression tests, including +`90% of the core tests`_ +not depending on C extension modules (most of the remaining 10% are arguably dependant on very obscure implementation details of CPython). -For some time now the bleeding edge PyPy work has been focused on generating -reasonably efficient C code from the source of PyPy, thereby reducing the -speed penalty. This goal is no longer far away. +The PyPy code base can be translated to a static executable. This is done +by generating either C or LLVM_ code, using the Boehm garbage collector or +(for C) reference counting. The result is around `300 times slower`_ than +CPython (this figure can vary quite a bit). + +.. _`90% of the core tests`: http://codespeak.net/~hpk/pypy-testresult/ +.. _`300 times slower`: faq.html#whysoslow Higher level picture @@ -84,7 +86,7 @@ The various parts of PyPy have always been under more or less heavy refactoring since its inception. However, the higher level architecture remains rather simple and unchanged. There are two independent basic -subsystems: +subsystems: `the Standard Interpreter`_ and `the Translation Process`_. The Standard Interpreter ------------------------ @@ -96,18 +98,12 @@ code objects and implementing bytecodes, - the `standard object space`_ which implements creation, access and - modification of application level objects, + modification of application level objects. Note that the *standard interpreter* can run fine on top of CPython (the C Implementation of Python led by Guido van Rossum), if one is willing to pay for the double-interpretation performance penalty. -In addition, the standard interpreter requires a parser and bytecode compiler -to turn the user's Python source code into a form amenable to -interpretation. This is currently still borrowed from CPython, but we -have two experimental parser modules in the source tree which are in the -process of being integrated. - The Translation Process ----------------------- @@ -118,15 +114,15 @@ - producing a *flow graph* representation of the standard interpreter. A combination of a `bytecode interpreter`_ and a *flow object space* performs *abstract interpretation* to record the flow of objects - and execution throughout a python program into such a *flow graph*. + and execution throughout a python program into such a *flow graph*; -- the *annotator* which performs type inference on the flow graph +- the *annotator* which performs type inference on the flow graph; - the *typer* which, based on the type annotations, turns the flow graph - into one using only low-level, C-like operations + into one using only low-level, C-like operations; - the *code generator* which translates the resulting flow graph into - another language, currently C or LLVM. + another language, currently C or LLVM_. See below for the `translation process in more details`_. @@ -136,16 +132,26 @@ The Bytecode Interpreter ========================= -The *plain bytecode interpreter* handles python code objects. The interpreter can -build code objects from Python sources, when needed, by invoking Python's -builtin compiler (we also have a way of constructing those code objects -from python source only, but we have not integrated it yet). Code objects +The *plain bytecode interpreter* handles python code objects. +The interpreter can build code objects from Python sources, +when needed, by invoking a bytecode compiler. Code objects are a nicely preprocessed, structured representation of source code, and -their main content is *bytecode*. In addition, code objects also know +their main content is *bytecode*. We use the same compact bytecode format +than CPython 2.4. + +Our bytecode compiler is implemented as a chain of flexible passes +(tokenizer, lexer, parser, abstract syntax tree builder, bytecode generator). +The latter passes are based on the ``compiler`` package from the standard +library of CPython, with various improvements and bug fixes. (The +bytecode compiler was recently integrated to the rest of the standard +interpreter -- it is still in development and not really documented yet.) + +In addition to storing bytecode, code objects also know how to create a *frame* object which has the responsibility to *interpret* a code object's bytecode. Each bytecode is implemented by a python function, which, in turn, delegates operations on -application-level objects to an object space. +application-level objects to an object space. This interpretation and +delegation is the core of the bytecode interpreter. This part is implemented in the `interpreter/`_ directory. People familiar with the CPython implementation of the above concepts will easily recognize @@ -378,12 +384,12 @@ The actual low-level code (and, in fact, also other high-level code) is emitted by "visiting" the type-annotated flow graph. Currently we have -a C-producing backend, and an LLVM-producing backend. The former also +a C-producing backend, and an LLVM_-producing backend. The former also accepts non-annotated or partially-annotated graphs, which allow us to test it on a larger class of programs than what the Annotator can (or ever will) fully process. -A new piece of this puzzle, still being integrated (May 2005), is the +The newest piece of this puzzle is the *Typer*, which inputs the high-level types inferred by the Annotator and uses them to modify the flow graph in-place to replace its operations with low-level ones, directly manipulating C-like values and data structures. @@ -394,5 +400,6 @@ .. _`RPython`: coding-guide.html#rpython .. _`abstract interpretation`: theory.html#abstract-interpretation .. _`translation document`: translation.html +.. _LLVM: http://llvm.cs.uiuc.edu/ .. include:: _ref.txt Modified: pypy/release/0.7.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/faq.txt (original) +++ pypy/release/0.7.x/pypy/doc/faq.txt Fri Aug 26 20:12:16 2005 @@ -11,6 +11,7 @@ On the other hand, the really interesting question is: Why is PyPy so slow? +.. _whysoslow: Why is PyPy so slow? From cfbolz at codespeak.net Fri Aug 26 20:21:13 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 20:21:13 +0200 (CEST) Subject: [pypy-svn] r16680 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826182113.655DE27B69@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 20:21:11 2005 New Revision: 16680 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: rename the option -laptop to -t-lowmem because lots of non-laptop computers have not enough memory for translation either. Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Fri Aug 26 20:21:11 2005 @@ -38,8 +38,8 @@ be either .py or .zip . -llinterpret interprets the flow graph after rtyping it - -laptop try to save as much memory as possible, since laptops tend to - have less than a gigabyte of memory (512 MB is typical). + -t-lowmem try to save as much memory as possible, since many computers + tend to have less than a gigabyte of memory (512 MB is typical). Currently, we avoid to use geninterplevel, which creates a lot of extra blocks, but gains only som 10-20 % of speed, because we are still lacking annotation of applevel code. @@ -107,7 +107,7 @@ policy = AnnotatorPolicy() if target: - spec = target(not options['-laptop']) + spec = target(not options['-t-lowmem']) try: entry_point, inputtypes, policy = spec except ValueError: @@ -358,7 +358,7 @@ '-fork': False, '-fork2': False, '-llinterpret': False, - '-laptop': False, + '-t-lowmem': False, '-batch': False, } listen_port = None From arigo at codespeak.net Fri Aug 26 20:22:36 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 20:22:36 +0200 (CEST) Subject: [pypy-svn] r16681 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826182236.9799027B6C@code1.codespeak.net> Author: arigo Date: Fri Aug 26 20:22:36 2005 New Revision: 16681 Modified: pypy/release/0.7.x/pypy/doc/translation.txt Log: This URL change is not valid right now, but should be done because the old URL will become invalid as soon as we merge the release branch back into the trunk. Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Fri Aug 26 20:22:36 2005 @@ -951,7 +951,7 @@ The LLVM Back-End ================= -http://codespeak.net/svn/pypy/dist/pypy/translator/llvm2/ +http://codespeak.net/svn/pypy/dist/pypy/translator/llvm/ XXX to be written From rxe at codespeak.net Fri Aug 26 20:26:00 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Fri, 26 Aug 2005 20:26:00 +0200 (CEST) Subject: [pypy-svn] r16682 - in pypy/release/0.7.x/pypy/translator/llvm: . test Message-ID: <20050826182600.C183527B6C@code1.codespeak.net> Author: rxe Date: Fri Aug 26 20:25:58 2005 New Revision: 16682 Added: pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py Modified: pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py pypy/release/0.7.x/pypy/translator/llvm/test/test_class.py pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py pypy/release/0.7.x/pypy/translator/llvm/test/test_exception.py pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm.py pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py pypy/release/0.7.x/pypy/translator/llvm/test/test_lltype.py pypy/release/0.7.x/pypy/translator/llvm/test/test_seq.py pypy/release/0.7.x/pypy/translator/llvm/test/test_snippet.py pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py Log: Refactor entry point to compiling and skipping tests. Modified: pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py Fri Aug 26 20:25:58 2005 @@ -15,6 +15,8 @@ EXCEPTIONS_SWITCHES = "-enable-correct-eh-support" SIMPLE_OPTIMIZATION_SWITCHES = (" ".join([ + # kill code - hopefully to speed things up + "-globaldce -adce -deadtypeelim -simplifycfg", # call %malloc -> malloc inst "-raiseallocs", Added: pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py Fri Aug 26 20:25:58 2005 @@ -0,0 +1,18 @@ +import py +from pypy.translator.llvm.genllvm import compile_module + +optimize_tests = False + +def llvm_is_on_path(): + try: + py.path.local.sysfind("llvm-as") + except py.error.ENOENT: + return False + return True + +def compile_function(function, annotation, **kwds): + if not llvm_is_on_path(): + py.test.skip("llvm not found") + + mod = compile_module(function, annotation, optimize=optimize_tests, **kwds) + return getattr(mod, 'pypy_' + function.func_name + "_wrapper") Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_class.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_class.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_class.py Fri Aug 26 20:25:58 2005 @@ -3,7 +3,7 @@ from pypy.translator.translator import Translator from pypy.objspace.flow.model import Constant, Variable -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.llvm.test import llvmsnippet #py.log.setconsumer("genllvm", py.log.STDOUT) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py Fri Aug 26 20:25:58 2005 @@ -1,6 +1,6 @@ import py import sys -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift def test_zerodiv_int(): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_exception.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_exception.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_exception.py Fri Aug 26 20:25:58 2005 @@ -1,6 +1,6 @@ import py -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.test.snippet import try_raise_choose from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_extfunc.py Fri Aug 26 20:25:58 2005 @@ -5,7 +5,7 @@ import py from pypy.tool.udir import udir -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.rpython.rarithmetic import r_uint py.log.setconsumer("genllvm", py.log.STDOUT) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py Fri Aug 26 20:25:58 2005 @@ -2,7 +2,7 @@ import py from pypy.translator.llvm.genllvm import use_boehm_gc -from pypy.translator.llvm.genllvm import compile_module_function +from pypy.translator.llvm.test.runtest import compile_function py.log.setconsumer("genllvm", py.log.STDOUT) py.log.setconsumer("genllvm database prepare", None) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm.py Fri Aug 26 20:25:58 2005 @@ -4,7 +4,7 @@ import py from pypy.rpython.rarithmetic import r_uint -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function py.log.setconsumer("genllvm", py.log.STDOUT) py.log.setconsumer("genllvm database prepare", None) Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py Fri Aug 26 20:25:58 2005 @@ -5,7 +5,7 @@ from pypy.translator.translator import Translator from pypy.objspace.flow.model import Constant, Variable -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.llvm.test import llvmsnippet class TestGenLLVM(object): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_lltype.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_lltype.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_lltype.py Fri Aug 26 20:25:58 2005 @@ -3,7 +3,7 @@ from pypy.rpython import lltype -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.llvm import database, codewriter from pypy.rpython import rarithmetic Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_seq.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_seq.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_seq.py Fri Aug 26 20:25:58 2005 @@ -3,7 +3,7 @@ from pypy.translator.translator import Translator from pypy.objspace.flow.model import Constant, Variable -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.llvm.test import llvmsnippet class TestLLVMArray(object): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_snippet.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_snippet.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_snippet.py Fri Aug 26 20:25:58 2005 @@ -1,6 +1,6 @@ from __future__ import division -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.test import snippet as test class TestSnippet(object): Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py Fri Aug 26 20:25:58 2005 @@ -4,7 +4,7 @@ from pypy.translator.test import snippet from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift -from pypy.translator.llvm.genllvm import compile_function +from pypy.translator.llvm.test.runtest import compile_function def test_call_five(): def wrapper(): From nik at codespeak.net Fri Aug 26 20:26:31 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 20:26:31 +0200 (CEST) Subject: [pypy-svn] r16683 - pypy/dist/pypy/module/_sre Message-ID: <20050826182631.2922327B6C@code1.codespeak.net> Author: nik Date: Fri Aug 26 20:26:28 2005 New Revision: 16683 Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/app_sre.py pypy/dist/pypy/module/_sre/interp_sre.py Log: converted and enabled fast_search. refactored getlower to be more efficient on interp-level. removed unneeded imports from app-level. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Fri Aug 26 20:26:28 2005 @@ -17,7 +17,7 @@ } interpleveldefs = { - 'getlower': 'interp_sre.getlower', + 'getlower': 'interp_sre.w_getlower', '_State': 'interp_sre.make_state', '_match': 'interp_sre.w_match', '_search': 'interp_sre.w_search', Modified: pypy/dist/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/app_sre.py (original) +++ pypy/dist/pypy/module/_sre/app_sre.py Fri Aug 26 20:26:28 2005 @@ -7,12 +7,8 @@ copyrighted by: Copyright (c) 1997-2001 by Secret Labs AB """ -import array, operator, sys -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 +import sys import _sre -from _sre import CODESIZE def compile(pattern, flags, code, groups=0, groupindex={}, indexgroup=[None]): @@ -289,45 +285,3 @@ def __deepcopy__(): raise TypeError, "cannot copy this pattern object" - - -def fast_search(state, pattern_codes): - """Skips forward in a string as fast as possible using information from - an optimization info block.""" - # pattern starts with a known prefix - # <5=length> <6=skip> <7=prefix data> - flags = pattern_codes[2] - prefix_len = pattern_codes[5] - prefix_skip = pattern_codes[6] # don't really know what this is good for - prefix = pattern_codes[7:7 + prefix_len] - overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] - i = 0 - string_position = state.string_position - while string_position < state.end: - while True: - if ord(state.string[string_position]) != prefix[i]: - if i == 0: - break - else: - i = overlap[i] - else: - i += 1 - if i == prefix_len: - # found a potential match - state.start = string_position + 1 - prefix_len - state.string_position = string_position + 1 \ - - prefix_len + prefix_skip - if flags & SRE_INFO_LITERAL: - return True # matched all of pure literal pattern - if _sre._match(state, pattern_codes[2 * prefix_skip:]): - return True - i = overlap[i] - break - string_position += 1 - return False - - -def _log(message): - if 0: - print message Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 20:26:28 2005 @@ -11,6 +11,7 @@ #### Exposed functions # XXX can we import those safely from sre_constants? +SRE_INFO_PREFIX = 1 SRE_INFO_LITERAL = 2 SRE_FLAG_LOCALE = 4 # honour system locale SRE_FLAG_UNICODE = 32 # use unicode locale @@ -18,16 +19,17 @@ OPCODE_LITERAL = 19 MAXREPEAT = 65535 -def getlower(space, w_char_ord, w_flags): - char_ord = space.int_w(w_char_ord) - flags = space.int_w(w_flags) +def w_getlower(space, w_char_ord, w_flags): + return space.wrap(getlower(space, space.int_w(w_char_ord), space.int_w(w_flags))) + +def getlower(space, char_ord, flags): if (char_ord < 128) or (flags & SRE_FLAG_UNICODE) \ or (flags & SRE_FLAG_LOCALE and char_ord < 256): w_uni_char = space.newunicode([char_ord]) w_lowered = space.call_method(w_uni_char, "lower") - return space.ord(w_lowered) + return space.int_w(space.ord(w_lowered)) else: - return space.wrap(char_ord) + return char_ord #### Core classes @@ -102,9 +104,7 @@ self.marks_stack.pop() def lower(self, char_ord): - # XXX this is ugly - space = self.space - return space.int_w(getlower(space, space.wrap(char_ord), space.wrap(self.flags))) + return getlower(self.space, char_ord, self.flags) def interp_attrproperty_int(name, cls): "NOT_RPYTHON: initialization-time only" @@ -236,9 +236,8 @@ if pattern_codes[0] == OPCODE_INFO: # optimization info block # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> - # XXX fast_search temporarily disabled - #if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: - # return state.fast_search(pattern_codes) + if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: + return fast_search(space, state, pattern_codes) flags = pattern_codes[2] pattern_codes = pattern_codes[pattern_codes[1] + 1:] @@ -251,6 +250,44 @@ string_position += 1 return False +def fast_search(space, state, pattern_codes): + """Skips forward in a string as fast as possible using information from + an optimization info block.""" + # pattern starts with a known prefix + # <5=length> <6=skip> <7=prefix data> + flags = pattern_codes[2] + prefix_len = pattern_codes[5] + prefix_skip = pattern_codes[6] # don't really know what this is good for + prefix = pattern_codes[7:7 + prefix_len] + overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] + pattern_codes = pattern_codes[pattern_codes[1] + 1:] + i = 0 + string_position = state.string_position + while string_position < state.end: + while True: + char_ord = space.int_w(space.ord( + space.getitem(state.w_string, space.wrap(string_position)))) + if char_ord != prefix[i]: + if i == 0: + break + else: + i = overlap[i] + else: + i += 1 + if i == prefix_len: + # found a potential match + state.start = string_position + 1 - prefix_len + state.string_position = string_position + 1 \ + - prefix_len + prefix_skip + if flags & SRE_INFO_LITERAL: + return True # matched all of pure literal pattern + if match(space, state, pattern_codes[2 * prefix_skip:]): + return True + i = overlap[i] + break + string_position += 1 + return False + def w_match(space, w_state, w_pattern_codes): pattern_codes = [space.int_w(code) for code in space.unpackiterable(w_pattern_codes)] From cfbolz at codespeak.net Fri Aug 26 20:29:22 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 20:29:22 +0200 (CEST) Subject: [pypy-svn] r16684 - pypy/release/0.7.x/pypy/doc/image Message-ID: <20050826182922.C450627B6C@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 20:29:21 2005 New Revision: 16684 Added: pypy/release/0.7.x/pypy/doc/image/translation.pdf (contents, props changed) Log: add a pdf version of the diagram as well to be able to reference it from the website. Added: pypy/release/0.7.x/pypy/doc/image/translation.pdf ============================================================================== Binary file. No diff available. From arigo at codespeak.net Fri Aug 26 20:39:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 20:39:23 +0200 (CEST) Subject: [pypy-svn] r16685 - in pypy/release/0.7.x/pypy: doc translator/c/src Message-ID: <20050826183923.068DA27B6C@code1.codespeak.net> Author: arigo Date: Fri Aug 26 20:39:20 2005 New Revision: 16685 Modified: pypy/release/0.7.x/pypy/doc/translation.txt pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Log: Simplified c/src/ll_os.h, which was more or less the first function written in this style. Later we decided to always have zero-terminated strings. Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Fri Aug 26 20:39:20 2005 @@ -1328,20 +1328,10 @@ int LL_os_open(RPyString *filename, int flag, int mode) { - char buf[PATH_MAX]; - int fd, namelen = RPyString_Size(filename); - if (namelen >= PATH_MAX) { - RPYTHON_RAISE_OSERROR(ENAMETOOLONG); - return -1; - } - else { - memcpy(buf, RPyString_AsString(filename), namelen); - buf[namelen] = 0; - fd = open(buf, flag, mode); - if (fd < 0) - RPYTHON_RAISE_OSERROR(errno); - return fd; - } + int fd = open(RPyString_AsString(filename), flag, mode); + if (fd < 0) + RPYTHON_RAISE_OSERROR(errno); + return fd; } One test for all this can be found in Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/src/ll_os.h (original) +++ pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Fri Aug 26 20:39:20 2005 @@ -39,20 +39,10 @@ int LL_os_open(RPyString *filename, int flag, int mode) { /* XXX unicode_file_names */ - char buf[PATH_MAX]; - int fd, namelen = RPyString_Size(filename); - if (namelen >= PATH_MAX) { - RPYTHON_RAISE_OSERROR(ENAMETOOLONG); - return -1; - } - else { - memcpy(buf, RPyString_AsString(filename), namelen); - buf[namelen] = 0; - fd = open(buf, flag, mode); - if (fd < 0) - RPYTHON_RAISE_OSERROR(errno); - return fd; - } + int fd = open(RPyString_AsString(filename), flag, mode); + if (fd < 0) + RPYTHON_RAISE_OSERROR(errno); + return fd; } long LL_read_into(int fd, RPyString *buffer) From cfbolz at codespeak.net Fri Aug 26 20:39:31 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 20:39:31 +0200 (CEST) Subject: [pypy-svn] r16686 - pypy/release/0.7.x/pypy/doc/image Message-ID: <20050826183931.7E44E27B70@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 20:39:30 2005 New Revision: 16686 Modified: pypy/release/0.7.x/pypy/doc/image/translation.pdf pypy/release/0.7.x/pypy/doc/image/translation.sxd Log: small fixes Modified: pypy/release/0.7.x/pypy/doc/image/translation.pdf ============================================================================== Binary files. No diff available. Modified: pypy/release/0.7.x/pypy/doc/image/translation.sxd ============================================================================== Binary files. No diff available. From cfbolz at codespeak.net Fri Aug 26 20:48:18 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 20:48:18 +0200 (CEST) Subject: [pypy-svn] r16687 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826184818.B96AE27B69@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 20:48:17 2005 New Revision: 16687 Modified: pypy/release/0.7.x/pypy/doc/coding-guide.txt Log: removed obsolete stati of the tracker. Modified: pypy/release/0.7.x/pypy/doc/coding-guide.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/coding-guide.txt (original) +++ pypy/release/0.7.x/pypy/doc/coding-guide.txt Fri Aug 26 20:48:17 2005 @@ -818,10 +818,9 @@ unread chatting - need-eg (jargon for "need example") in-progress testing - done-cbb (jargon for 'done, could-be-better') + duplicate resolved .. _`register with the tracker`: https://codespeak.net/issue/pypy-dev/user?@template=register From cfbolz at codespeak.net Fri Aug 26 20:50:12 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 20:50:12 +0200 (CEST) Subject: [pypy-svn] r16688 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826185012.1EFAD27B69@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 20:50:11 2005 New Revision: 16688 Modified: pypy/release/0.7.x/pypy/doc/architecture.txt pypy/release/0.7.x/pypy/doc/translation.txt Log: added paragraph on how to use the llinterpreter for testing. added links to the translation graph. Modified: pypy/release/0.7.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.7.x/pypy/doc/architecture.txt Fri Aug 26 20:50:11 2005 @@ -395,11 +395,12 @@ low-level ones, directly manipulating C-like values and data structures. The complete translation process is described in more details in the -`translation document`_. +`translation document`_. There is a graph_ that gives an overview over the +whole process. .. _`RPython`: coding-guide.html#rpython .. _`abstract interpretation`: theory.html#abstract-interpretation .. _`translation document`: translation.html .. _LLVM: http://llvm.cs.uiuc.edu/ - +.. _graph: image/translation.pdf .. include:: _ref.txt Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Fri Aug 26 20:50:11 2005 @@ -21,7 +21,8 @@ of the translation process. It is available as an interactive utility to `play around`_. -Here are the steps we follow to translate a given program: +There is a graph_ that gives an overview over the different steps of the +translation process. These are: 1. The complete program is imported. If needed, extra initialization is performed. Once this is done, the program must be present in memory as @@ -57,7 +58,7 @@ .. _`Common Lisp`: http://codespeak.net/svn/pypy/dist/pypy/translator/gencl.py .. _Pyrex: http://codespeak.net/svn/pypy/dist/pypy/translator/pyrex/genpyrex.py .. _Java: http://codespeak.net/svn/pypy/dist/pypy/translator/java/ - +.. _graph: image/translation.pdf .. _Annotator: @@ -920,6 +921,41 @@ exception-catching links.) +The LLInterpreter +----------------- + +The LLInterpreter is a simply piece of code that is able to interpret flow +graphs. This is very useful for testing purposes, especially if you work on +the `RPython Typer`_. The most useful interface for it is the ``interpret`` +function in the file `pypy/rpython/test/test_llinterp.py`_. It takes as +arguments a function and a list of arguments with which the function is +supposed to be called. Then it generates the flow graph, annotates is +according to the types of the arguments you passed to it and runs the +LLInterpreter on the result. Example:: + + def test_invert(): + def f(x): + return ~x + res = interpret(f, [3]) + assert res == ~3 + +Furthermore there is a function ``interpret_raises`` which behaves much like +``py.test.raises``. It takes an exception as a first argument, the function to +be called as a second and the list of function arguments as a third. Example:: + + def test_raise(): + def raise_exception(i): + if i == 42: + raise IndexError + elif i == 43: + raise ValueError + return i + res = interpret(raise_exception, [41]) + assert res == 41 + interpret_raises(IndexError, raise_exception, [42]) + interpret_raises(ValueError, raise_exception, [43]) + +.. _`pypy/rpython/test/test_llinterp.py`: ../rpython/test/test_llinterp.py .. _C: .. _GenC: From pedronis at codespeak.net Fri Aug 26 20:54:22 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 26 Aug 2005 20:54:22 +0200 (CEST) Subject: [pypy-svn] r16689 - in pypy/release/0.7.x/pypy: interpreter module/sys Message-ID: <20050826185422.D9AF027B69@code1.codespeak.net> Author: pedronis Date: Fri Aug 26 20:54:21 2005 New Revision: 16689 Modified: pypy/release/0.7.x/pypy/interpreter/interactive.py pypy/release/0.7.x/pypy/module/sys/__init__.py Log: introduce a pypy_version_info attribute on our sys module, use it in interactive to produce the banner Modified: pypy/release/0.7.x/pypy/interpreter/interactive.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/interactive.py (original) +++ pypy/release/0.7.x/pypy/interpreter/interactive.py Fri Aug 26 20:54:21 2005 @@ -127,10 +127,10 @@ # sys.version, self.__class__.__name__, # self.space.__class__.__name__) w_sys = self.space.sys - version = self.space.str_w(self.space.getattr(w_sys, self.space.wrap('version'))) + major, minor, micro, _, _ = self.space.unwrap(self.space.sys.get('pypy_version_info')) elapsed = time.time() - self.space._starttime - banner = "PyPy %s in %s on top of Python %s (startupttime: %.2f secs)" % ( - version.split()[2],self.space.__repr__(), sys.version.split()[0], elapsed) + banner = "PyPy %d.%d.%d in %s on top of Python %s (startupttime: %.2f secs)" % ( + major, minor, micro ,self.space.__repr__(), sys.version.split()[0], elapsed) code.InteractiveConsole.interact(self, banner) def raw_input(self, prompt=""): Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/sys/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/sys/__init__.py Fri Aug 26 20:54:21 2005 @@ -50,7 +50,8 @@ 'copyright' : 'space.wrap("MIT-License")', 'api_version' : 'space.wrap(1012)', 'version_info' : 'space.wrap((2,4,1, "alpha", 42))', - 'version' : 'space.wrap("2.4.1 (pypy 0.7.0beta build)")', + 'version' : 'space.wrap("2.4.1 (pypy 0.7.0 build)")', + 'pypy_version_info' : 'space.wrap((0,7,0, "alpha", 0))', 'hexversion' : 'space.wrap(0x020401a0)', 'ps1' : 'space.wrap(">>>> ")', 'ps2' : 'space.wrap(".... ")', From tismer at codespeak.net Fri Aug 26 21:17:23 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 21:17:23 +0200 (CEST) Subject: [pypy-svn] r16690 - in pypy/release/0.7.x/pypy: interpreter module/posix/test rpython/module/test Message-ID: <20050826191723.EC62D27B69@code1.codespeak.net> Author: tismer Date: Fri Aug 26 21:17:17 2005 New Revision: 16690 Modified: pypy/release/0.7.x/pypy/interpreter/baseobjspace.py pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py pypy/release/0.7.x/pypy/rpython/module/test/test_posix.py Log: made the import os posix create the right name, as it appears in "os.name". Disabled a test of ftruncate for windows. Modified: pypy/release/0.7.x/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/baseobjspace.py (original) +++ pypy/release/0.7.x/pypy/interpreter/baseobjspace.py Fri Aug 26 21:17:17 2005 @@ -6,6 +6,7 @@ from pypy.interpreter.miscutils import ThreadLocals from pypy.tool.cache import Cache from pypy.rpython.rarithmetic import r_uint, intmask +import os __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'BaseWrappable', 'W_Root'] @@ -190,6 +191,9 @@ # that differs from the app-visible name (because you # can specify implementation variants) builtinmodule_list = [(x, None) for x in modules] + bml = builtinmodule_list + if ('posix', None) in bml: + bml[bml.index( ('posix', None) )] = (os.name, 'posix') if self.options.parser == "pypy": builtinmodule_list.append(('parser', 'recparser')) builtinmodule_list.append(('symbol', None)) Modified: pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py (original) +++ pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py Fri Aug 26 21:17:17 2005 @@ -1,5 +1,6 @@ from pypy.objspace.std import StdObjSpace from pypy.tool.udir import udir +import os def setup_module(mod): mod.space = StdObjSpace(usemodules=['posix']) @@ -9,7 +10,7 @@ class AppTestPosix: def setup_class(cls): cls.space = space - cls.w_posix = space.appexec([], "(): import posix ; return posix") + cls.w_posix = space.appexec([], "(): import %s as m ; return m" % os.name) cls.w_path = space.wrap(str(path)) def test_posix_is_pypy_s(self): Modified: pypy/release/0.7.x/pypy/rpython/module/test/test_posix.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/module/test/test_posix.py (original) +++ pypy/release/0.7.x/pypy/rpython/module/test/test_posix.py Fri Aug 26 21:17:17 2005 @@ -1,6 +1,7 @@ from pypy.rpython.test.test_llinterp import interpret from pypy.tool.udir import udir -import os, posix +import os +exec 'import %s as posix' % os.name def setup_module(module): testf = udir.join('test.txt') @@ -99,4 +100,6 @@ fi = os.open(path,os.O_RDWR,0777) func = interpret(f,[fi,6]) assert os.fstat(fi).st_size == 6 - + +if not hasattr(os, 'ftruncate'): + del test_ftruncate From arigo at codespeak.net Fri Aug 26 21:21:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 26 Aug 2005 21:21:43 +0200 (CEST) Subject: [pypy-svn] r16691 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826192143.1F01427B4E@code1.codespeak.net> Author: arigo Date: Fri Aug 26 21:21:42 2005 New Revision: 16691 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: default target: targetpypystandalone Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Fri Aug 26 21:21:42 2005 @@ -10,7 +10,7 @@ targetspec.py is a python file defining what is the translation target and setting things up for it, it should have a target function returning an entry_point ...; - defaults to targetpypymain. The .py suffix is optional. + defaults to targetpypystandalone. The .py suffix is optional. -text Don't start the Pygame viewer -no-a Don't infer annotations, just translate everything -no-t Don't type-specialize the graph operations with the C typer @@ -334,7 +334,7 @@ if __name__ == '__main__': - targetspec = 'targetpypymain' + targetspec = 'targetpypystandalone' huge = 100 load_file = None save_file = None From tismer at codespeak.net Fri Aug 26 21:23:21 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 21:23:21 +0200 (CEST) Subject: [pypy-svn] r16692 - in pypy/release/0.7.x/pypy: module/posix rpython rpython/module rpython/module/test translator/c translator/c/src translator/c/test Message-ID: <20050826192321.5B26727B56@code1.codespeak.net> Author: tismer Date: Fri Aug 26 21:23:15 2005 New Revision: 16692 Added: pypy/release/0.7.x/pypy/rpython/ros.py (contents, props changed) Modified: pypy/release/0.7.x/pypy/module/posix/__init__.py pypy/release/0.7.x/pypy/module/posix/interp_posix.py pypy/release/0.7.x/pypy/rpython/extfunctable.py pypy/release/0.7.x/pypy/rpython/module/ll_os.py pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py pypy/release/0.7.x/pypy/translator/c/extfunc.py pypy/release/0.7.x/pypy/translator/c/src/ll_os.h pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Log: added putenv and environ to os. That was particularly interesting, because we have to keep the putenv arguments alive, like CPython does. Modified: pypy/release/0.7.x/pypy/module/posix/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/posix/__init__.py Fri Aug 26 21:23:15 2005 @@ -31,9 +31,12 @@ 'chdir' : 'interp_posix.chdir', 'mkdir' : 'interp_posix.mkdir', 'rmdir' : 'interp_posix.rmdir', + 'environ' : 'interp_posix.get(space).w_environ' } if hasattr(os, 'ftruncate'): interpleveldefs['ftruncate'] = 'interp_posix.ftruncate' + if hasattr(os, 'putenv'): + interpleveldefs['putenv'] = 'interp_posix.putenv' for constant in dir(os): Modified: pypy/release/0.7.x/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/interp_posix.py (original) +++ pypy/release/0.7.x/pypy/module/posix/interp_posix.py Fri Aug 26 21:23:15 2005 @@ -1,5 +1,6 @@ from pypy.interpreter.baseobjspace import ObjSpace from pypy.rpython.rarithmetic import intmask +from pypy.rpython import ros from pypy.interpreter.error import OperationError import os @@ -77,7 +78,7 @@ lst = [st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], st[8], st[9]] w_tuple = space.newtuple([space.wrap(intmask(x)) for x in lst]) - w_stat_result = space.getattr(space.getbuiltinmodule('posix'), + w_stat_result = space.getattr(space.getbuiltinmodule(os.name), space.wrap('stat_result')) return space.call_function(w_stat_result, w_tuple) @@ -178,3 +179,43 @@ except OSError, e: raise wrap_oserror(space, e) rmdir.unwrap_spec = [ObjSpace, str] + + +# this is a particular case, because we need to supply +# the storage for the environment variables, at least +# for some OSes. + +class State: + def __init__(self, space): + self.posix_putenv_garbage = {} + self.w_environ = space.newdict([]) + _convertenviron(space, self.w_environ) +def get(space): + return space.fromcache(State) + +def _convertenviron(space, w_env): + idx = 0 + while 1: + s = ros.environ(idx) + if s is None: + break + p = s.find('='); + if p >= 0: + assert p >= 0 + key = s[:p] + value = s[p+1:] + space.setitem(w_env, space.wrap(key), space.wrap(value)) + idx += 1 + +def putenv(space, name, value): + """putenv(key, value) + +Change or add an environment variable.""" + txt = '%s=%s' % name, value + ros.putenv(txt) + # Install the first arg and newstr in posix_putenv_garbage; + # this will cause previous value to be collected. This has to + # happen after the real putenv() call because the old value + # was still accessible until then. + get(space).posix_putenv_garbage[name] = txt +putenv.unwrap_spec = [ObjSpace, str, str] Modified: pypy/release/0.7.x/pypy/rpython/extfunctable.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/extfunctable.py (original) +++ pypy/release/0.7.x/pypy/rpython/extfunctable.py Fri Aug 26 21:23:15 2005 @@ -128,6 +128,10 @@ from pypy.annotation.model import SomeTuple, SomeFloat return SomeTuple((SomeFloat(), SomeFloat())) +def strnullannotation(*args): + from pypy.annotation.model import SomeString + return SomeString(can_be_None=True) + # external function declarations declare(os.open , int , 'll_os/open') declare(os.read , str , 'll_os/read') @@ -193,6 +197,12 @@ declare(rarithmetic.formatd, str, 'll_strtod/formatd') # ___________________________________________________________ +# special helpers for os with no equivalent +from pypy.rpython import ros +declare(ros.putenv, noneannotation, 'll_os/putenv') +declare(ros.environ, strnullannotation, 'll_os/environ') + +# ___________________________________________________________ # the exceptions that can be implicitely raised by some operations standardexceptions = { TypeError : True, Modified: pypy/release/0.7.x/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/module/ll_os.py (original) +++ pypy/release/0.7.x/pypy/rpython/module/ll_os.py Fri Aug 26 21:23:15 2005 @@ -17,7 +17,7 @@ from pypy.rpython.rstr import STR from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy - +from pypy.rpython import ros def ll_os_open(fname, flag, mode): return os.open(from_rstr(fname), flag, mode) @@ -133,3 +133,13 @@ def ll_os_rmdir(path): os.rmdir(from_rstr(path)) ll_os_rmdir.suggested_primitive = True + +# this function is not really the os thing, but the internal one. +def ll_os_putenv(name_eq_value): + ros.putenv(from_rstr(name_eq_value)) +ll_os_putenv.suggested_primitive = True + +# get the initial environment as a string list +def ll_os_environ(idx): + return ros.environ(idx) +ll_os_environ.suggested_primitive = True Modified: pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py Fri Aug 26 21:23:15 2005 @@ -35,3 +35,20 @@ assert data == 0 assert file(filename).read().strip() == '2' os.unlink(filename) + +def test_putenv(): + filename = str(udir.join('test_putenv.txt')) + arg = to_rstr('abcdefgh=12345678') + ll_os_putenv(arg) + cmd = '''python -c "import os; print os.environ['abcdefgh']" > %s''' % filename + os.system(cmd) + assert file(filename).read().strip() == '12345678' + os.unlink(filename) + +def test_environ(): + count = 0 + while 1: + if not ll_os_environ(count): + break + count += 1 + assert count == len(os.environ.keys()) Added: pypy/release/0.7.x/pypy/rpython/ros.py ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/rpython/ros.py Fri Aug 26 21:23:15 2005 @@ -0,0 +1,17 @@ +""" +Helper file for Python equivalents of os specific calls. +""" + +import os + +def putenv(name_eq_value): + # we fake it with the real one + name, value = name_eq_value.split('=', 1) + os.putenv(name, value) + +_initial_items = os.environ.items() + +def environ(idx): + # we simulate the environ list + if idx < len(_initial_items): + return '%s=%s' % _initial_items[idx] Modified: pypy/release/0.7.x/pypy/translator/c/extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/extfunc.py Fri Aug 26 21:23:15 2005 @@ -27,6 +27,8 @@ ll_os .ll_os_chdir: 'LL_os_chdir', ll_os .ll_os_mkdir: 'LL_os_mkdir', ll_os .ll_os_rmdir: 'LL_os_rmdir', + ll_os .ll_os_putenv: 'LL_os_putenv', + ll_os .ll_os_environ: 'LL_os_environ', ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', ll_time.ll_time_time: 'LL_time_time', Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/src/ll_os.h (original) +++ pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Fri Aug 26 21:23:15 2005 @@ -201,3 +201,43 @@ RPYTHON_RAISE_OSERROR(errno); } } + +#ifdef HAVE_PUTENV + +/* note that this doesn't map to os.putenv, it is the name=value + * version of C. See ros.py for the fake implementation. + * Note that we are responsible to keep the + * value alive. This is done in interp_posix.py + */ +void LL_os_putenv(RPyString * name_eq_value) { + int error = putenv(RPyString_AsString(name_eq_value)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} +#endif + +/* Return a dictionary corresponding to the POSIX environment table */ +/*** actually, we create a sring list here and do the rest in posix */ +#ifdef WITH_NEXT_FRAMEWORK +/* On Darwin/MacOSX a shared library or framework has no access to +** environ directly, we must obtain it with _NSGetEnviron(). +*/ +#include +static char **environ; +#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) +extern char **environ; +#endif /* !_MSC_VER */ + +RPyString* LL_os_environ(int idx) { + RPyString *rs = NULL; + char *s; +#ifdef WITH_NEXT_FRAMEWORK + if (environ == NULL) + environ = *_NSGetEnviron(); +#endif + if (environ != NULL && (s = environ[idx]) != NULL) { + rs = RPyString_FromString(s); + } + return rs; +} \ No newline at end of file Modified: pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Fri Aug 26 21:23:15 2005 @@ -4,6 +4,7 @@ from pypy.tool.udir import udir from pypy.translator.c.test.test_genc import compile from pypy.translator.c.extfunc import EXTERNALS +from pypy.rpython import ros def test_all_suggested_primitives(): for modulename in ['ll_math', 'll_os', 'll_os_path', 'll_time']: @@ -423,3 +424,28 @@ f1(dirname, True) assert not os.path.exists(dirname) +def test_putenv(): + def put(s): + ros.putenv(s) + func = compile(put, [str]) + filename = str(udir.join('test_putenv.txt')) + func('abcdefgh=12345678') + cmd = '''python -c "import os; print os.environ['abcdefgh']" > %s''' % filename + os.system(cmd) + assert file(filename).read().strip() == '12345678' + os.unlink(filename) + +def test_environ(): + def env(idx): + # need to as if the result is NULL, or we crash + ret = ros.environ(idx) + if ret is None: + return False + return ret + func = compile(env, [int]) + count = 0 + while 1: + if not func(count): + break + count += 1 + assert count == len(os.environ.keys()) From tismer at codespeak.net Fri Aug 26 21:35:51 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 21:35:51 +0200 (CEST) Subject: [pypy-svn] r16693 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826193551.D15A627B4E@code1.codespeak.net> Author: tismer Date: Fri Aug 26 21:35:50 2005 New Revision: 16693 Modified: pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh Log: when changing translate_pypy.py, please don't forget to sanitize runtranslate.sh as well. Modified: pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh (original) +++ pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh Fri Aug 26 21:35:50 2005 @@ -1,8 +1,8 @@ export RTYPERORDER=order,module-list.pedronis # stopping on the first error -#python translate_pypy.py -no-c -no-o -text -no-snapshot -fork +#python translate_pypy.py -no-c -no-o -text -fork # running it all -python translate_pypy.py targetpypystandalone -text -no-snapshot $* +python translate_pypy.py targetpypystandalone -text $* # How to work in parallel: From ludal at codespeak.net Fri Aug 26 22:06:41 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 22:06:41 +0200 (CEST) Subject: [pypy-svn] r16694 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826200641.E59A327B60@code1.codespeak.net> Author: ludal Date: Fri Aug 26 22:06:40 2005 New Revision: 16694 Modified: pypy/release/0.7.x/pypy/doc/README.compiling Log: wrote the full readme hopfully explaining the current status and reasons for having 4 compiler options Modified: pypy/release/0.7.x/pypy/doc/README.compiling ============================================================================== --- pypy/release/0.7.x/pypy/doc/README.compiling (original) +++ pypy/release/0.7.x/pypy/doc/README.compiling Fri Aug 26 22:06:40 2005 @@ -2,7 +2,103 @@ Compiling approaches -------------------------- -stable: use interpreter/stablecompiler at interp-level -_stable: use lib/_stablecompiler at applevel. -ast: use in-development translatable interplevel compiling. -cpython: use cpython builtin c-level compiler. +PyPy includes four compiling approaches which are reflecting the +states of different part of its compiling pipeline. + +You can select one of this approach by use of the --compiler option. +The options are: +- stable: use interpreter/stablecompiler at interp-level +- _stable: use lib/_stablecompiler at applevel. +- ast: use in-development translatable interplevel compiling. +- cpython: use cpython builtin c-level compiler. + +The following is a more detailed explanation of each option. + +The compiling pipeline comprises three parts: +- the tokenizer turns source code into tokens +- the parser analyzes a sequence of tokens and if it's grammatically + correct it turns it into an internal representation called a parse + tree or a syntax tree +- the compiler turns the internal representation into code objects containing + bytecode + +the --compiler option of pypy selects a full compiling pipeline +including the tokenizer, parser, and actual compiler. + +The existence of those different parts is explained by several needs: +to fully translate pypy, all code running at interpreter level needs to be +translatable. +If some part is not translatable we need to interpret it at application level +The compiler module from c-python is entirely written in python which is good +but it is far from being translatable +We keep c-python implementations for testing purposes (because its much faster) +For the same reasons we keep some code at interpreter level which is not translatable. + +tokenizer +--------- +there is only two tokenizer in pypy. ones is c-python's own tokenizer +and the other one is an automata based recognizer + +parser +------ +as for the tokenizer there is two (three) parsers one from c-python and one home-made +parser. +The pypy parser can build different kinds of representations with the help +of a 'builder' object and pypy can use two builders: +- tuplebuilder produces a representation similar to that of the c-python parser module + the building of the internal representation is fully annotatable, unfortunately we + need to transform this representation into a tree of tuples which is an operation + that cannot be annotatable +- astbuilder is a builder that directly produces the Abstract Syntax Tree needed by + the pypy compiler to produce code objects. The astbuilder is fully annotatable and + so can run at interpreter level + +compiler +-------- +again we have the choice between c-python's own compiler and pypy compiler +The pypy compiler is based on the compiler package from c-python. +It contains two main parts : the transformer living in transformer.py and +the ast to bytecode compiler implemented mainly in pycodegen.py and pyassem.py + +The transformer turns tuple into an AST (Abstract Syntax Tree). +The AST to bytecode transforms the AST into bytecode. +To summarize: +- when we use the tuplebuilder from the parser we feed its output to + the transformer first and then feed the AST to the AST to bytecode compiler +- when we use the astbuilder from the parser we can feed its output directly to + the AST to bytecode compiler + +The compiler package has been modified and splitted into three different versions. + +interpreter/stablecompiler: this version mostly contains bug fixes and is the closer + to the original c-python implementation + +lib/_stablecompiler: this version is very similar to stable but needs to run at + application-level (that is interpreted by pypy itself) + which means that it cannot use things like 'eval' which + would recursively call itself. +interpreter/astcompiler: this version intends to be run at interpreter level + and be translatable. it is heavily modified and doesn't + use the transformer since we provide directly the ast + tree produced by the astbuilder + +So in summary the four options correspond to the following: + +stable: uses the pypy parser with the tuplebuilder feeding tuples to the transformer + and compiler from the interpreter/stablecompiler + this version is not translatable because the compiler and transformer are not. + +_stable: uses the pypy parser with the tuplebuilder feeding tuples to + the application-level transformer and compiler from lib/_stablecompiler + this version is fully translatable at the cost of running the transformer + and compiler at application level + +ast: uses the pypy parser with the astbuilder feeding the AST tree to + the compiler from interpreter/astcompiler + this version is intended to be fully translatable. This is a work in progress. + it can be used instead of stable except some corner case compliance test won't + pass yet. + +cpython: uses the c-python builtin `compile` function to compile the source code + this version uses a c-builtin so it's not translatable but much faster + (note that the speed gain is only during compilation, exec and eval) From ludal at codespeak.net Fri Aug 26 22:13:50 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 22:13:50 +0200 (CEST) Subject: [pypy-svn] r16695 - in pypy/release/0.7.x: lib-python/modified-2.4.1/test lib-python/modified-2.4.1/test/output pypy/interpreter/stablecompiler pypy/lib/_stablecompiler pypy/objspace Message-ID: <20050826201350.00BBB27B47@code1.codespeak.net> Author: ludal Date: Fri Aug 26 22:13:46 2005 New Revision: 16695 Added: pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_compile.py - copied, changed from r16671, pypy/release/0.7.x/lib-python/2.4.1/test/test_compile.py Modified: pypy/release/0.7.x/lib-python/modified-2.4.1/test/output/test_extcall pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_unpack.py pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py pypy/release/0.7.x/pypy/objspace/descroperation.py Log: + more work on compliance tests - adding/changing error messages - checking None and __debug__ assignments - from xxx import a,b,c, syntax checks - duplicate arguments in function/lambda defs - non-default after default arguments - 'iteration over non-sequence' error message Modified: pypy/release/0.7.x/lib-python/modified-2.4.1/test/output/test_extcall ============================================================================== --- pypy/release/0.7.x/lib-python/modified-2.4.1/test/output/test_extcall (original) +++ pypy/release/0.7.x/lib-python/modified-2.4.1/test/output/test_extcall Fri Aug 26 22:13:46 2005 @@ -25,8 +25,8 @@ got multiple values for keyword argument 'a' keywords must be strings h() got an unexpected keyword argument 'e' -object is not iter()-able -object is not iter()-able +iteration over non-sequence +iteration over non-sequence object None is not callable argument after ** must be a dictionary argument after ** must be a dictionary Modified: pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_unpack.py ============================================================================== --- pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_unpack.py (original) +++ pypy/release/0.7.x/lib-python/modified-2.4.1/test/test_unpack.py Fri Aug 26 22:13:46 2005 @@ -55,7 +55,7 @@ >>> a, b, c = 7 Traceback (most recent call last): ... - TypeError: object is not iter()-able + TypeError: iteration over non-sequence Unpacking tuple of wrong size Modified: pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py Fri Aug 26 22:13:46 2005 @@ -126,13 +126,19 @@ } self.encoding = None - def syntaxerror( self, msg, node ): + def syntaxerror(self, msg, node): offset = 0 - text = "return x!" + text = "" lineno = extractLineNo( node ) args = ( self.filename, lineno, offset, text ) raise SyntaxError( msg, args ) + def none_assignment_error(self, assigning, node): + if assigning==OP_DELETE: + self.syntaxerror( "deleting None", node ) + else: + self.syntaxerror( "assignment to None", node ) + def transform(self, tree): """Transform an AST into a modified parse tree.""" if not (isinstance(tree, tuple) or isinstance(tree, list)): @@ -280,6 +286,8 @@ assert isinstance(code, Stmt) assert isinstance(code.nodes[0], Discard) del code.nodes[0] + if name == "None": + self.none_assignment_error( OP_ASSIGN, nodelist[-4] ) return Function(decorators, name, names, defaults, flags, doc, code, lineno=lineno) @@ -315,6 +323,8 @@ assert isinstance(code.nodes[0], Discard) del code.nodes[0] + if name == "None": + self.none_assignment_error(OP_ASSIGN, nodelist[1]) return Class(name, bases, doc, code, lineno=nodelist[1][2]) def stmt(self, nodelist): @@ -458,7 +468,12 @@ return From(fromname, [('*', None)], lineno=nodelist[0][2]) else: - node = nodelist[3 + (nodelist[3][0] == token.LPAR)] + if nodelist[3][0] == token.LPAR: + node = nodelist[4] + else: + node = nodelist[3] + if node[-1][0] == token.COMMA: + self.syntaxerror("trailing comma not allowed without surrounding parentheses", node) return From(fromname, self.com_import_as_names(node), lineno=nodelist[0][2]) @@ -801,7 +816,11 @@ if node[0] == token.STAR: node = nodelist[i+1] if node[0] == token.NAME: - names.append(node[1]) + name = node[1] + if name in names: + self.syntaxerror("duplicate argument '%s' in function definition" % + name, node) + names.append(name) flags = flags | CO_VARARGS i = i + 3 @@ -812,28 +831,38 @@ node = nodelist[i+1] else: raise ValueError, "unexpected token: %s" % t - names.append(node[1]) + name = node[1] + if name in names: + self.syntaxerror("duplicate argument '%s' in function definition" % + name, node) + names.append(name) flags = flags | CO_VARKEYWORDS break # fpdef: NAME | '(' fplist ')' - names.append(self.com_fpdef(node)) + name = self.com_fpdef(node) + if name in names: + self.syntaxerror("duplicate argument '%s' in function definition" % + name, node) + names.append(name) i = i + 1 if i >= len(nodelist): + if len(defaults): + self.syntaxerror("non-default argument follows default argument",node) break - + if nodelist[i][0] == token.EQUAL: defaults.append(self.com_node(nodelist[i + 1])) i = i + 2 elif len(defaults): - # XXX This should be a syntax error. - # Treat "(a=1, b)" as "(a=1, b=None)" - defaults.append(Const(None)) + self.syntaxerror("non-default argument follows default argument",node) i = i + 1 + if "None" in names: + self.syntaxerror( "Invalid syntax. Assignment to None.", node) return names, defaults, flags def com_fpdef(self, node): @@ -942,6 +971,11 @@ Names, slices, and attributes are the only allowable nodes. """ l = self.com_node(node) + if isinstance(l, Name): + if l.name == "__debug__": + self.syntaxerror( "can not assign to __debug__", node ) + if l.name == "None": + self.none_assignment_error( OP_ASSIGN, node ) if l.__class__ in (Name, Slice, Subscript, Getattr): return l self.syntaxerror( "can't assign to %s" % l.__class__.__name__, node) @@ -984,6 +1018,10 @@ self.syntaxerror( "can't assign to []", node) return self.com_assign_list(node, assigning) elif t == token.NAME: + if node[1][1] == "__debug__": + self.syntaxerror( "can not assign to __debug__", node ) + if node[1][1] == "None": + self.none_assignment_error(assigning, node) return self.com_assign_name(node[1], assigning) else: self.syntaxerror( "can't assign to literal", node) @@ -1026,6 +1064,8 @@ self.syntaxerror( "unknown trailer type: %s" % t, node) def com_assign_attr(self, primary, node, assigning): + if node[1]=="None": + self.none_assignment_error(assigning, node) return AssAttr(primary, node[1], assigning, lineno=node[-1]) def com_binary(self, constructor, nodelist): Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py Fri Aug 26 22:13:46 2005 @@ -123,13 +123,19 @@ } self.encoding = None - def syntaxerror( self, msg, node ): + def syntaxerror(self, msg, node): offset = 0 - text = "return x!" + text = "" lineno = extractLineNo( node ) args = ( self.filename, lineno, offset, text ) raise SyntaxError( msg, args ) + def none_assignment_error(self, assigning, node): + if assigning==OP_DELETE: + self.syntaxerror( "deleting None", node ) + else: + self.syntaxerror( "assignment to None", node ) + def transform(self, tree): """Transform an AST into a modified parse tree.""" if not (isinstance(tree, tuple) or isinstance(tree, list)): @@ -277,6 +283,8 @@ assert isinstance(code, Stmt) assert isinstance(code.nodes[0], Discard) del code.nodes[0] + if name == "None": + self.none_assignment_error( OP_ASSIGN, nodelist[-4] ) return Function(decorators, name, names, defaults, flags, doc, code, lineno=lineno) @@ -312,6 +320,8 @@ assert isinstance(code.nodes[0], Discard) del code.nodes[0] + if name == "None": + self.none_assignment_error(OP_ASSIGN, nodelist[1]) return Class(name, bases, doc, code, lineno=nodelist[1][2]) def stmt(self, nodelist): @@ -455,7 +465,12 @@ return From(fromname, [('*', None)], lineno=nodelist[0][2]) else: - node = nodelist[3 + (nodelist[3][0] == token.LPAR)] + if nodelist[3][0] == token.LPAR: + node = nodelist[4] + else: + node = nodelist[3] + if node[-1][0] == token.COMMA: + self.syntaxerror("trailing comma not allowed without surrounding parentheses", node) return From(fromname, self.com_import_as_names(node), lineno=nodelist[0][2]) @@ -797,7 +812,11 @@ if node[0] == token.STAR: node = nodelist[i+1] if node[0] == token.NAME: - names.append(node[1]) + name = node[1] + if name in names: + self.syntaxerror("duplicate argument '%s' in function definition" % + name, node) + names.append(name) flags = flags | CO_VARARGS i = i + 3 @@ -808,28 +827,38 @@ node = nodelist[i+1] else: raise ValueError, "unexpected token: %s" % t - names.append(node[1]) + name = node[1] + if name in names: + self.syntaxerror("duplicate argument '%s' in function definition" % + name, node) + names.append(name) flags = flags | CO_VARKEYWORDS break # fpdef: NAME | '(' fplist ')' - names.append(self.com_fpdef(node)) + name = self.com_fpdef(node) + if name in names: + self.syntaxerror("duplicate argument '%s' in function definition" % + name, node) + names.append(name) i = i + 1 if i >= len(nodelist): + if len(defaults): + self.syntaxerror("non-default argument follows default argument",node) break - + if nodelist[i][0] == token.EQUAL: defaults.append(self.com_node(nodelist[i + 1])) i = i + 2 elif len(defaults): - # XXX This should be a syntax error. - # Treat "(a=1, b)" as "(a=1, b=None)" - defaults.append(Const(None)) + self.syntaxerror("non-default argument follows default argument",node) i = i + 1 + if "None" in names: + self.syntaxerror( "Invalid syntax. Assignment to None.", node) return names, defaults, flags def com_fpdef(self, node): @@ -938,6 +967,11 @@ Names, slices, and attributes are the only allowable nodes. """ l = self.com_node(node) + if isinstance(l, Name): + if l.name == "__debug__": + self.syntaxerror( "can not assign to __debug__", node ) + if l.name == "None": + self.none_assignment_error( OP_ASSIGN, node ) if l.__class__ in (Name, Slice, Subscript, Getattr): return l self.syntaxerror( "can't assign to %s" % l.__class__.__name__, node) @@ -980,6 +1014,10 @@ self.syntaxerror( "can't assign to []", node) return self.com_assign_list(node, assigning) elif t == token.NAME: + if node[1][1] == "__debug__": + self.syntaxerror( "can not assign to __debug__", node ) + if node[1][1] == "None": + self.none_assignment_error(assigning, node) return self.com_assign_name(node[1], assigning) else: self.syntaxerror( "can't assign to literal", node) @@ -1022,6 +1060,8 @@ self.syntaxerror( "unknown trailer type: %s" % t, node) def com_assign_attr(self, primary, node, assigning): + if node[1]=="None": + self.none_assignment_error(assigning, node) return AssAttr(primary, node[1], assigning, lineno=node[-1]) def com_binary(self, constructor, nodelist): Modified: pypy/release/0.7.x/pypy/objspace/descroperation.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/descroperation.py (original) +++ pypy/release/0.7.x/pypy/objspace/descroperation.py Fri Aug 26 22:13:46 2005 @@ -177,7 +177,7 @@ w_descr = space.lookup(w_obj, '__getitem__') if w_descr is None: raise OperationError(space.w_TypeError, - space.wrap("object is not iter()-able")) + space.wrap("iteration over non-sequence")) return space.newseqiter(w_obj) return space.get_and_call_function(w_descr, w_obj) From tismer at codespeak.net Fri Aug 26 22:22:29 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 22:22:29 +0200 (CEST) Subject: [pypy-svn] r16696 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050826202229.D6C3527B47@code1.codespeak.net> Author: tismer Date: Fri Aug 26 22:22:28 2005 New Revision: 16696 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: fixed some typos Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Fri Aug 26 22:22:28 2005 @@ -41,9 +41,9 @@ -t-lowmem try to save as much memory as possible, since many computers tend to have less than a gigabyte of memory (512 MB is typical). Currently, we avoid to use geninterplevel, which creates a lot - of extra blocks, but gains only som 10-20 % of speed, because + of extra blocks, but gains only some 10-20 % of speed, because we are still lacking annotation of applevel code. - -batch don't use interactive helpers,like pdb + -batch don't use interactive helpers, like pdb """ import autopath, sys, os From tismer at codespeak.net Fri Aug 26 22:23:36 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 26 Aug 2005 22:23:36 +0200 (CEST) Subject: [pypy-svn] r16697 - in pypy/release/0.7.x/pypy: module/posix rpython rpython/module rpython/module/test translator/c translator/c/src translator/c/test Message-ID: <20050826202336.0161827B47@code1.codespeak.net> Author: tismer Date: Fri Aug 26 22:23:32 2005 New Revision: 16697 Modified: pypy/release/0.7.x/pypy/module/posix/__init__.py pypy/release/0.7.x/pypy/module/posix/interp_posix.py pypy/release/0.7.x/pypy/rpython/extfunctable.py pypy/release/0.7.x/pypy/rpython/module/ll_os.py pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py pypy/release/0.7.x/pypy/translator/c/extfunc.py pypy/release/0.7.x/pypy/translator/c/src/ll_os.h pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Log: added unsetenv to posix. XXX need to test this on Linux, tomorrow. tests are to be added, there is XXX now. Modified: pypy/release/0.7.x/pypy/module/posix/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/posix/__init__.py Fri Aug 26 22:23:32 2005 @@ -2,6 +2,7 @@ from pypy.interpreter.mixedmodule import MixedModule import os +exec 'import %s as posix' % os.name class Module(MixedModule): """This module provides access to operating system functionality that is @@ -37,6 +38,8 @@ interpleveldefs['ftruncate'] = 'interp_posix.ftruncate' if hasattr(os, 'putenv'): interpleveldefs['putenv'] = 'interp_posix.putenv' + if hasattr(posix, 'unsetenv'): # note: emulated in os + interpleveldefs['unsetenv'] = 'interp_posix.unsetenv' for constant in dir(os): Modified: pypy/release/0.7.x/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/interp_posix.py (original) +++ pypy/release/0.7.x/pypy/module/posix/interp_posix.py Fri Aug 26 22:23:32 2005 @@ -211,7 +211,7 @@ """putenv(key, value) Change or add an environment variable.""" - txt = '%s=%s' % name, value + txt = '%s=%s' % (name, value) ros.putenv(txt) # Install the first arg and newstr in posix_putenv_garbage; # this will cause previous value to be collected. This has to @@ -219,3 +219,15 @@ # was still accessible until then. get(space).posix_putenv_garbage[name] = txt putenv.unwrap_spec = [ObjSpace, str, str] + +def unsetenv(space, name): + """unsetenv(key) + +Delete an environment variable.""" + os.unsetenv(name) + # Remove the key from posix_putenv_garbage; + # this will cause it to be collected. This has to + # happen after the real unsetenv() call because the + # old value was still accessible until then. + del get(space).posix_putenv_garbage[name] +unsetenv.unwrap_spec = [ObjSpace, str] Modified: pypy/release/0.7.x/pypy/rpython/extfunctable.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/extfunctable.py (original) +++ pypy/release/0.7.x/pypy/rpython/extfunctable.py Fri Aug 26 22:23:32 2005 @@ -151,6 +151,7 @@ declare(os.chdir , noneannotation, 'll_os/chdir') declare(os.mkdir , noneannotation, 'll_os/mkdir') declare(os.rmdir , noneannotation, 'll_os/rmdir') +declare(os.unsetenv , noneannotation, 'll_os/unsetenv') declare(os.path.exists, bool , 'll_os_path/exists') declare(os.path.isdir, bool , 'll_os_path/isdir') declare(time.time , float , 'll_time/time') @@ -199,7 +200,7 @@ # ___________________________________________________________ # special helpers for os with no equivalent from pypy.rpython import ros -declare(ros.putenv, noneannotation, 'll_os/putenv') +declare(ros.putenv, noneannotation, 'll_os/putenv') declare(ros.environ, strnullannotation, 'll_os/environ') # ___________________________________________________________ Modified: pypy/release/0.7.x/pypy/rpython/module/ll_os.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/module/ll_os.py (original) +++ pypy/release/0.7.x/pypy/rpython/module/ll_os.py Fri Aug 26 22:23:32 2005 @@ -139,7 +139,11 @@ ros.putenv(from_rstr(name_eq_value)) ll_os_putenv.suggested_primitive = True -# get the initial environment as a string list +def ll_os_unsetenv(name): + os.unsetenv(from_rstr(name)) +ll_os_unsetenv.suggested_primitive = True + +# get the initial environment by indexing def ll_os_environ(idx): return ros.environ(idx) ll_os_environ.suggested_primitive = True Modified: pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py Fri Aug 26 22:23:32 2005 @@ -45,6 +45,8 @@ assert file(filename).read().strip() == '12345678' os.unlink(filename) +# XXX missing test for unsetenv, please do this on Linux + def test_environ(): count = 0 while 1: Modified: pypy/release/0.7.x/pypy/translator/c/extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/extfunc.py Fri Aug 26 22:23:32 2005 @@ -28,6 +28,7 @@ ll_os .ll_os_mkdir: 'LL_os_mkdir', ll_os .ll_os_rmdir: 'LL_os_rmdir', ll_os .ll_os_putenv: 'LL_os_putenv', + ll_os .ll_os_unsetenv:'LL_os_unsetenv', ll_os .ll_os_environ: 'LL_os_environ', ll_time.ll_time_clock: 'LL_time_clock', ll_time.ll_time_sleep: 'LL_time_sleep', Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/src/ll_os.h (original) +++ pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Fri Aug 26 22:23:32 2005 @@ -203,10 +203,9 @@ } #ifdef HAVE_PUTENV - -/* note that this doesn't map to os.putenv, it is the name=value +/* Note that this doesn't map to os.putenv, it is the name=value * version of C. See ros.py for the fake implementation. - * Note that we are responsible to keep the + * Also note that we are responsible to keep the * value alive. This is done in interp_posix.py */ void LL_os_putenv(RPyString * name_eq_value) { @@ -217,6 +216,15 @@ } #endif +#ifdef HAVE_UNSETENV +void LL_os_unsetenv(RPyString * name) { + int error = unsetenv(RPyString_AsString(name)); + if (error != 0) { + RPYTHON_RAISE_OSERROR(errno); + } +} +#endif + /* Return a dictionary corresponding to the POSIX environment table */ /*** actually, we create a sring list here and do the rest in posix */ #ifdef WITH_NEXT_FRAMEWORK Modified: pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Fri Aug 26 22:23:32 2005 @@ -435,6 +435,8 @@ assert file(filename).read().strip() == '12345678' os.unlink(filename) +# XXX missing test for unsetenv, please do this on Linux + def test_environ(): def env(idx): # need to as if the result is NULL, or we crash From ludal at codespeak.net Fri Aug 26 22:34:30 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 22:34:30 +0200 (CEST) Subject: [pypy-svn] r16698 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826203430.B1E6027B47@code1.codespeak.net> Author: ludal Date: Fri Aug 26 22:34:29 2005 New Revision: 16698 Modified: pypy/release/0.7.x/pypy/doc/parser.txt Log: small doc update Modified: pypy/release/0.7.x/pypy/doc/parser.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/parser.txt (original) +++ pypy/release/0.7.x/pypy/doc/parser.txt Fri Aug 26 22:34:29 2005 @@ -59,6 +59,12 @@ S = Sequence( A, Alternative( Token('+'), Token('-') ), A ) +Status +====== + +See README.compiling on the status of the parser(s) implementation of PyPy + + Detailed design =============== @@ -137,25 +143,59 @@ Examples using the parser within PyPy ------------------------------------- +The four parser variants are used from within interpreter/pycompiler.py API Quickref ------------ Modules +~~~~~~~ + +* interpreter/pyparser contains the tokenizer and grammar parser +* interpreter/astcompiler contains the soon to be rpythonic compiler +* interpreter/stablecompiler contains the compiler used by default +* lib/_stablecompiler contains a modified version of stablecompiler capable + of running at application level (that is not recursively calling itself + while compiling) + Main facade functions +~~~~~~~~~~~~~~~~~~~~~ -Grammar +Grammar +~~~~~~~ Long term goals =============== +having enough flexibility in the design that allows us to change the +grammar at runtime. Such modification needs to be able to: +* modify the grammar representation +* modify the ast builder so it produces existing or new AST nodes +* add new AST nodes +* modify the compiler so that it knows how to deal with new AST nodes + + parser implementation +--------------------- +We can now build AST trees directly from the parser. +Still missing is the ability to easily provide/change building functions +easily. The functions are referenced at interpreter level through a dictionnary +mapping that has rule names as keys. + compiler implementation +----------------------- +For now we are working at translating the existing compiler module without +changing it's design too much. That means we won't have enough flexibility +to be able to handle new AST nodes at runtime. parser module +------------- +enhance the parser module interface so that it allows acces to the internal grammar +representation, and allows to modify it too. compiler module - +--------------- +same as above From ludal at codespeak.net Fri Aug 26 22:43:37 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 22:43:37 +0200 (CEST) Subject: [pypy-svn] r16700 - pypy/release/0.7.x/pypy/interpreter/pyparser/test Message-ID: <20050826204337.6C59727B49@code1.codespeak.net> Author: ludal Date: Fri Aug 26 22:43:34 2005 New Revision: 16700 Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_samples.py Log: fixed the tests broken by the change to Transformer Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py Fri Aug 26 22:43:34 2005 @@ -534,7 +534,7 @@ return builder def tuple_parse_expr(expr, target='single'): - t = Transformer() + t = Transformer("dummyfile") return ast_from_input(expr, target, t) def check_expression(expr, target='single'): Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_samples.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_samples.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_samples.py Fri Aug 26 22:43:34 2005 @@ -100,7 +100,7 @@ # compare the two tuples by transforming them into AST, to hide irrelevant # differences -- typically newlines at the end of the tree. print 'Comparing the ASTs of', testname - transformer1 = PyPyTransformer() + transformer1 = PyPyTransformer("") ast_pypy = transformer1.compile_node(pypy_tuples) repr_pypy = repr(ast_pypy) From cfbolz at codespeak.net Fri Aug 26 22:44:36 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 26 Aug 2005 22:44:36 +0200 (CEST) Subject: [pypy-svn] r16701 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826204436.9156F27B49@code1.codespeak.net> Author: cfbolz Date: Fri Aug 26 22:44:34 2005 New Revision: 16701 Modified: pypy/release/0.7.x/pypy/doc/_ref.txt pypy/release/0.7.x/pypy/doc/getting-started.txt Log: update and improve a bit the getting-started document: changed release version to 0.7.0, added instructions on how to translate your own PyPy version Modified: pypy/release/0.7.x/pypy/doc/_ref.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/_ref.txt (original) +++ pypy/release/0.7.x/pypy/doc/_ref.txt Fri Aug 26 22:44:34 2005 @@ -51,4 +51,7 @@ .. _`translator/c/`: ../../pypy/translator/c .. _`translator/java/`: ../../pypy/translator/java .. _`translator/llvm/`: ../../pypy/translator/llvm -.. _`translator/tool/`: ../../pypy/translator/tool \ No newline at end of file +.. _`translator/tool/`: ../../pypy/translator/too +.. _`pypy/rpython`: ../../pypy/rpython +.. _`pypy/rpython/rtyper.py`: ../../pypy/rpython/rtyper.py +.. _`pypy/rpython/lltype.py`: ../../pypy/rpython/lltype.py Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Fri Aug 26 22:44:34 2005 @@ -10,22 +10,19 @@ Just the facts ============== -getting & running the PyPy 0.6.1 release +getting & running the PyPy 0.7 release ----------------------------------------- - Note that the 0.6 release was broken and - thus you find only the 0.6.1 release here. - Download one of the following release files and unpack it: -*pypy-0.6.1 (05/21/2005)* +*pypy-0.7 - * download one of `pypy-0.6.1.tar.bz2`_, `pypy-0.6.1.tar.gz`_ or - `pypy-0.6.1.zip`_ (windows line-endings) and unpack it + * download one of `pypy-0.7.0.tar.bz2`_, `pypy-0.7.0.tar.gz`_ or + `pypy-0.7.0.zip`_ (windows line-endings) and unpack it - * alternatively run ``svn co http://codespeak.net/svn/pypy/release/0.6.1 pypy-0.6.1`` + * alternatively run ``svn co http://codespeak.net/svn/pypy/release/0.7.0 pypy-0.7.0`` -then change to the ``pypy-0.6.1`` directory +then change to the ``pypy-0.7.0`` directory and execute the following command line:: python pypy/bin/py.py @@ -41,9 +38,9 @@ for guidance on how to continue. .. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.6.1.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.6.1.tar.bz2 -.. _`pypy-0.6.1.zip`: http://codespeak.net/download/pypy/pypy-0.6.1.zip -.. _`pypy-0.6.1.tar.gz`: http://codespeak.net/download/pypy/pypy-0.6.1.tar.gz +.. _`pypy-0.7.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 +.. _`pypy-0.7.0.zip`: http://codespeak.net/download/pypy/pypy-0.7.0.zip +.. _`pypy-0.7.0.tar.gz`: http://codespeak.net/download/pypy/pypy-0.7.0.tar.gz Svn-check out & run the latest PyPy as a two-liner -------------------------------------------------- @@ -346,25 +343,26 @@ >>> f = t.ccompile() The first command replaces operations with variables of types that are -avaiable in C (e.g. int) with low level versions. This can be ommited if no -annotation (see last subsection) has been performed. +avaiable in C (e.g. int) with low level versions. This can also be ommited +although it is not recommended. translating the flow graph to LLVM code +++++++++++++++++++++++++++++++++++++++ If you feel adventureous (and have `LLVM installed`_ and on your path) you can -also try to compile the graph with LLVM. This is still quite experimental -and only works with some functions: One of the most visible restriction is -that return type of the entry function has to be and int, float or bool. To -try it do:: +also try to compile the graph with LLVM_ (low level virtual machine). This +works nearly as well as for the c backend. There is a restriction, though: The +return type and the arguments of the entry function has to be an int, float or +bool. To try it do:: >>> print t.llvm() >>> f = t.llvmcompile(optimize=True) >>> f(28) 1 -This works only with fully annotated graphs. +In contrast to the C backend this works only for fully annotated and +specialized graphs. a slightly larger example +++++++++++++++++++++++++ @@ -387,21 +385,37 @@ ++++++++++++++++++++++++++++++++ Not for the faint of heart nor the owner of a very old machine: you can -run the annotator over the whole PyPy interpreter itself. This is the -largest and ultimate example of source that our annotator can (very -successfully!) process:: +translate the whole of PyPy to low level C code. This is the largest and +ultimate example of source that our translation toolchain can process:: cd pypy/translator/goal - python translate_pypy.py -no-t -no-c + python translate_pypy.py -Moving around is difficult because of the sheer size of the result. -For this reason, the debugger prompt you get at the end has been -enhanced with commands to facilitate locating functions and classes. -Type ``help graphs`` for a list of the new commands. Help is also +This whole process will take some time and quite a lot of memory. To reduce +the memory footprint of the translation process you can use the option +``-t_lowmem`` With this option the whole process should be runnable on a +machine with 512Mb of RAM. If the translation is finished running and after +you closed the graph you will be greeted by the friendly prompt of a PyPy +executable that is not running on top of CPython any more. + +Moving around in the resulting flow graph is difficult because of the sheer +size of the result. For this reason, the debugger prompt you get at +the end has been enhanced with commands to facilitate locating functions and +classes. Type ``help graphs`` for a list of the new commands. Help is also available on each of these new commands. The ``translate_pypy`` script itself takes a number of options controlling -what to translate and how. See ``translate_pypy.py -h``. Try out:: +what to translate and how. See ``translate_pypy.py -h``. Some of the more +interesting options are: + + * ``-llvm``: produce code for LLVM_ instead of for C. One of the biggest + things not working there is threading. + + * ``-boehm``: use the `Boehm-Demers-Weiser garbage collector`_ instead of + our own reference counting implementation. + + +Try out:: cd pypy/translator/goal python translate_pypy.py targetrpystone @@ -410,7 +424,6 @@ python translate_pypy.py targetrpystone2 - .. _`start reading sources`: Where to start reading the sources @@ -446,6 +459,12 @@ can be inferred about a graph. The graph "walker" that uses this is in `pypy/translator/annrpython.py`_. +* `pypy/rpython`_ contains the code of the RPython typer. The typer transforms + annotated flow graphs in a way that makes them very similar to C code so + that they can be easy translated. The graph transformations are controlled + by the stuff in `pypy/rpython/rtyper.py`_. The object model that is used can + be found in `pypy/rpython/lltype.py`_. For each RPython type there is a + file rxxxx.py that contains the low level functions needed for this type. .. _optionaltool: @@ -466,6 +485,7 @@ pygame: http://www.pygame.org/download.shtml +.. _LLVM: .. _`LLVM installed`: LLVM @@ -556,5 +576,6 @@ .. _bug reports: https://codespeak.net/issue/pypy-dev/ .. _`directory reference`: index.html#directory-reference +.. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ .. include:: _ref.txt From ludal at codespeak.net Fri Aug 26 22:52:37 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 26 Aug 2005 22:52:37 +0200 (CEST) Subject: [pypy-svn] r16702 - pypy/release/0.7.x/pypy/interpreter/pyparser/test Message-ID: <20050826205237.EF6B827B49@code1.codespeak.net> Author: ludal Date: Fri Aug 26 22:52:35 2005 New Revision: 16702 Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py Log: - the test contained incorrect expressions which are now caught by the transformer Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astbuilder.py Fri Aug 26 22:52:35 2005 @@ -244,8 +244,8 @@ ] imports_newstyle = [ - 'from os import path, system,', - 'from os import path as P, system as S,', + 'from os import path, system', + 'from os import path as P, system as S', 'from os import (path as P, system as S,)', 'from os import *', ] From hpk at codespeak.net Fri Aug 26 22:53:39 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 26 Aug 2005 22:53:39 +0200 (CEST) Subject: [pypy-svn] r16703 - pypy/release/0.7.x/pypy/doc Message-ID: <20050826205339.2079827B49@code1.codespeak.net> Author: hpk Date: Fri Aug 26 22:53:37 2005 New Revision: 16703 Modified: pypy/release/0.7.x/pypy/doc/_ref.txt pypy/release/0.7.x/pypy/doc/getting-started.txt Log: fixed some ReST Modified: pypy/release/0.7.x/pypy/doc/_ref.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/_ref.txt (original) +++ pypy/release/0.7.x/pypy/doc/_ref.txt Fri Aug 26 22:53:37 2005 @@ -1,8 +1,8 @@ .. _`demo/`: ../../demo .. _`lib-python/`: ../../lib-python .. _`lib-python/2.4.1/dis.py`: ../../lib-python/2.4.1/dis.py -.. _`pypy/annotation`: -.. _`annotation/`: ../../pypy/annotation +.. _`annotation/`: +.. _`pypy/annotation`: ../../pypy/annotation .. _`annotation/binaryop.py`: ../../pypy/annotation/binaryop.py .. _`doc/`: ../../pypy/doc .. _`doc/revreport/`: ../../pypy/doc/revreport @@ -16,12 +16,12 @@ .. _`pypy/interpreter/nestedscope.py`: ../../pypy/interpreter/nestedscope.py .. _`pypy/interpreter/pyopcode.py`: ../../pypy/interpreter/pyopcode.py .. _`pypy/interpreter/typedef.py`: ../../pypy/interpreter/typedef.py -.. _`pypy/lib/`: -.. _`lib/`: ../../pypy/lib -.. _`pypy/lib/test2`: -.. _`lib/test2/`: ../../pypy/lib/test2 -.. _`pypy/module`: -.. _`module/`: ../../pypy/module +.. _`lib/`: +.. _`pypy/lib/`: ../../pypy/lib +.. _`lib/test2/`: +.. _`pypy/lib/test2`: ../../pypy/lib/test2 +.. _`module/`: +.. _`pypy/module`: ../../pypy/module .. _`module/__builtin__/`: ../../pypy/module/__builtin__ .. _`pypy/module/__builtin__/__init__.py`: ../../pypy/module/__builtin__/__init__.py .. _`module/_sre/`: ../../pypy/module/_sre @@ -31,27 +31,36 @@ .. _`objspace/`: .. _`pypy/objspace`: ../../pypy/objspace .. _`objspace/flow/`: ../../pypy/objspace/flow -.. _`pypy/objspace/std`: -.. _`objspace/std/`: ../../pypy/objspace/std +.. _`objspace/std/`: +.. _`pypy/objspace/std`: ../../pypy/objspace/std .. _`objspace/thunk.py`: ../../pypy/objspace/thunk.py .. _`objspace/trace.py`: .. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py -.. _`rpython/`: ../../pypy/rpython +.. _`rpython/`: +.. _`pypy/rpython`: ../../pypy/rpython +.. _`pypy/rpython/extfunctable.py`: ../../pypy/rpython/extfunctable.py +.. _`pypy/rpython/lltype.py`: .. _`rpython/lltype.py`: ../../pypy/rpython/lltype.py +.. _`pypy/rpython/module/`: ../../pypy/rpython/module +.. _`pypy/rpython/module/ll_os.py`: ../../pypy/rpython/module/ll_os.py +.. _`pypy/rpython/module/test`: ../../pypy/rpython/module/test .. _`rpython/rint.py`: ../../pypy/rpython/rint.py .. _`rpython/rlist.py`: ../../pypy/rpython/rlist.py .. _`rpython/rmodel.py`: ../../pypy/rpython/rmodel.py +.. _`pypy/rpython/rtyper.py`: ../../pypy/rpython/rtyper.py +.. _`pypy/rpython/test/test_llinterp.py`: ../../pypy/rpython/test/test_llinterp.py .. _`pypy/test_all.py`: ../../pypy/test_all.py .. _`tool/`: ../../pypy/tool .. _`tool/pytest/`: ../../pypy/tool/pytest .. _`tool/tb_server/`: ../../pypy/tool/tb_server -.. _`pypy/translator`: -.. _`translator/`: ../../pypy/translator +.. _`translator/`: +.. _`pypy/translator`: ../../pypy/translator .. _`pypy/translator/annrpython.py`: ../../pypy/translator/annrpython.py .. _`translator/c/`: ../../pypy/translator/c +.. _`pypy/translator/c/extfunc.py`: ../../pypy/translator/c/extfunc.py +.. _`pypy/translator/c/src/`: ../../pypy/translator/c/src +.. _`pypy/translator/c/src/ll_os.h`: ../../pypy/translator/c/src/ll_os.h +.. _`pypy/translator/c/test/test_extfunc.py`: ../../pypy/translator/c/test/test_extfunc.py .. _`translator/java/`: ../../pypy/translator/java .. _`translator/llvm/`: ../../pypy/translator/llvm -.. _`translator/tool/`: ../../pypy/translator/too -.. _`pypy/rpython`: ../../pypy/rpython -.. _`pypy/rpython/rtyper.py`: ../../pypy/rpython/rtyper.py -.. _`pypy/rpython/lltype.py`: ../../pypy/rpython/lltype.py +.. _`translator/tool/`: ../../pypy/translator/tool \ No newline at end of file Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Fri Aug 26 22:53:37 2005 @@ -15,7 +15,7 @@ Download one of the following release files and unpack it: -*pypy-0.7 +*pypy-0.7* * download one of `pypy-0.7.0.tar.bz2`_, `pypy-0.7.0.tar.gz`_ or `pypy-0.7.0.zip`_ (windows line-endings) and unpack it From nik at codespeak.net Fri Aug 26 23:00:47 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Fri, 26 Aug 2005 23:00:47 +0200 (CEST) Subject: [pypy-svn] r16705 - pypy/dist/pypy/module/_sre Message-ID: <20050826210047.63ACA27B52@code1.codespeak.net> Author: nik Date: Fri Aug 26 23:00:46 2005 New Revision: 16705 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: fix to make the annotate happy Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Fri Aug 26 23:00:46 2005 @@ -310,7 +310,7 @@ has_matched = context.has_matched if has_matched != context.UNDECIDED: # don't pop if context isn't done state.context_stack.pop() - return has_matched == context.MATCHED + return has_matched == MatchContext.MATCHED def dispatch_loop(space, context): """Returns MATCHED if the current context matches, NOT_MATCHED if it doesn't From hpk at codespeak.net Sat Aug 27 10:53:44 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 10:53:44 +0200 (CEST) Subject: [pypy-svn] r16707 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827085344.61DBF27B59@code1.codespeak.net> Author: hpk Date: Sat Aug 27 10:53:43 2005 New Revision: 16707 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: at least a note that the tarballs are not there yet Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 10:53:43 2005 @@ -13,6 +13,10 @@ getting & running the PyPy 0.7 release ----------------------------------------- +*please come back tomorrow when the following information +will become valid, in particular the tarballs are not +there yet* + Download one of the following release files and unpack it: *pypy-0.7* From ericvrp at codespeak.net Sat Aug 27 11:13:04 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 11:13:04 +0200 (CEST) Subject: [pypy-svn] r16709 - in pypy/release/0.7.x/pypy/translator/llvm: . demo test Message-ID: <20050827091304.DD19327B5B@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 11:13:03 2005 New Revision: 16709 Modified: pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py pypy/release/0.7.x/pypy/translator/llvm/demo/richards.py pypy/release/0.7.x/pypy/translator/llvm/genllvm.py pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py Log: bit of refactoring to get test_gc to pass Modified: pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py Sat Aug 27 11:13:03 2005 @@ -90,14 +90,14 @@ cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) if exe_name: - cmds.append("gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) + cmds.append("gcc %s.o %s -lm -ldl -o %s" % (b, gc_libs, exe_name)) object_files.append("%s.o" % b) else: #assume 64 bit platform (x86-64?) #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)) if exe_name: cmds.append("gcc %s.c -c -O2 -fomit-frame-pointer" % (b,)) - cmds.append("gcc %s.o -static %s -lm -o %s" % (b, gc_libs, exe_name)) + cmds.append("gcc %s.o %s -lm -ldl -o %s" % (b, gc_libs, exe_name)) source_files.append("%s.c" % b) try: Modified: pypy/release/0.7.x/pypy/translator/llvm/demo/richards.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/demo/richards.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/demo/richards.py Sat Aug 27 11:13:03 2005 @@ -360,7 +360,7 @@ class Richards: - iterations = 25 + iterations = 2 def run(self): for i in xrange(self.iterations): Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Sat Aug 27 11:13:03 2005 @@ -428,8 +428,3 @@ def compile_function(function, annotation, **kwds): mod = compile_module(function, annotation, **kwds) return getattr(mod, 'pypy_' + function.func_name + "_wrapper") - -def compile_module_function(function, annotation, **kwds): - mod = compile_module(function, annotation, **kwds) - f = getattr(mod, 'pypy_' + function.func_name + "_wrapper") - return mod, f Modified: pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py Sat Aug 27 11:13:03 2005 @@ -16,3 +16,11 @@ mod = compile_module(function, annotation, optimize=optimize_tests, **kwds) return getattr(mod, 'pypy_' + function.func_name + "_wrapper") + +def compile_module_function(function, annotation, **kwds): + if not llvm_is_on_path(): + py.test.skip("llvm not found") + + mod = compile_module(function, annotation, **kwds) + f = getattr(mod, 'pypy_' + function.func_name + "_wrapper") + return mod, f Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_gc.py Sat Aug 27 11:13:03 2005 @@ -2,7 +2,7 @@ import py from pypy.translator.llvm.genllvm import use_boehm_gc -from pypy.translator.llvm.test.runtest import compile_function +from pypy.translator.llvm.test.runtest import compile_module_function py.log.setconsumer("genllvm", py.log.STDOUT) py.log.setconsumer("genllvm database prepare", None) From cfbolz at codespeak.net Sat Aug 27 11:15:58 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 11:15:58 +0200 (CEST) Subject: [pypy-svn] r16710 - in pypy/release/0.7.x/pypy/module/posix: . test Message-ID: <20050827091558.DEF6427B5B@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 11:15:57 2005 New Revision: 16710 Modified: pypy/release/0.7.x/pypy/module/posix/__init__.py pypy/release/0.7.x/pypy/module/posix/app_posix.py pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py Log: implement os.fdopen. works only if you use PyPy's file implementation. Modified: pypy/release/0.7.x/pypy/module/posix/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/posix/__init__.py Sat Aug 27 11:15:57 2005 @@ -13,6 +13,7 @@ appleveldefs = { 'error' : 'app_posix.error', 'stat_result': 'app_posix.stat_result', + 'fdopen' : 'app_posix.fdopen', } interpleveldefs = { Modified: pypy/release/0.7.x/pypy/module/posix/app_posix.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/app_posix.py (original) +++ pypy/release/0.7.x/pypy/module/posix/app_posix.py Sat Aug 27 11:15:57 2005 @@ -22,3 +22,14 @@ st_atime = tuple_item_getter(7) st_mtime = tuple_item_getter(8) st_ctime = tuple_item_getter(9) + +def fdopen(fd, mode='r', buffering=None): + """fdopen(fd [, mode='r' [, buffering]]) -> file_object + + Return an open file object connected to a file descriptor.""" + + try: + return file.fdopen(fd, mode, buffering) + except AttributeError: + raise NotImplementedError, "fdopen only works if you use PyPy's file implementation." + Modified: pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py (original) +++ pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py Sat Aug 27 11:15:57 2005 @@ -63,3 +63,14 @@ ex(self.posix.stat, "qweqwehello") # how can getcwd() raise? ex(self.posix.dup, UNUSEDFD) + + def test_fdopen(self): + path = self.path + posix = self.posix + fd = posix.open(path, posix.O_RDONLY, 0777) + try: + f = posix.fdopen(fd, "r") + except NotImplementedError: + pass + else: + raise "did not raise" From hpk at codespeak.net Sat Aug 27 11:17:55 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 11:17:55 +0200 (CEST) Subject: [pypy-svn] r16711 - in pypy/release/0.7.x: lib-python pypy/lib/_stablecompiler Message-ID: <20050827091755.2161927B5B@code1.codespeak.net> Author: hpk Date: Sat Aug 27 11:17:54 2005 New Revision: 16711 Modified: pypy/release/0.7.x/lib-python/conftest.py pypy/release/0.7.x/pypy/lib/_stablecompiler/symbols.py Log: make our applevel-loaded _stablecompiler issue SyntaxWarnings/raise SyntaxErrors on too late global statements. Makes test_global.py pass (but you need to erase lib/_sre.py i think because using the app-level _sre really takes forever). added the possibility to specify the compiler for running compliance tests. Modified: pypy/release/0.7.x/lib-python/conftest.py ============================================================================== --- pypy/release/0.7.x/lib-python/conftest.py (original) +++ pypy/release/0.7.x/lib-python/conftest.py Sat Aug 27 11:17:54 2005 @@ -284,6 +284,7 @@ """ Regression Test Declaration.""" def __init__(self, basename, enabled=False, dumbtest=False, oldstyle=False, core=False, uselibfile=False, + compiler=None, usemodules = ''): self.basename = basename self.enabled = enabled @@ -294,6 +295,7 @@ self._oldstyle = oldstyle self._uselibfile = uselibfile self._usemodules = usemodules.split() + self.compiler = compiler self.core = core def oldstyle(self): @@ -512,7 +514,7 @@ RegrTest('test_gl.py', enabled=False, dumbtest=1), RegrTest('test_glob.py', enabled=True, core=True), - RegrTest('test_global.py', enabled=True, core=True), + RegrTest('test_global.py', enabled=True, core=True, compiler='_stable'), # this fails because it relies on the warnings module # turning a warning into an exception, but PyPy's # interplevel doesn't call into the app-level warnings @@ -874,6 +876,8 @@ pypy_options.append('--oldstyle') if regrtest.uselibfile: pypy_options.append('--uselibfile') + if regrtest.compiler: + pypy_options.append('--compiler=%s' % regrtest.compiler) pypy_options.extend( ['--usemodules=%s' % mod for mod in regrtest.usemodules]) sopt = " ".join(pypy_options) Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/symbols.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/symbols.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/symbols.py Sat Aug 27 11:17:54 2005 @@ -5,12 +5,21 @@ SC_UNKNOWN, SC_DEFAULT from misc import mangle import types - +import warnings import sys MANGLE_LEN = 256 +def issue_warning(msg, filename, lineno): + try: + warnings.warn_explicit(msg, SyntaxWarning, filename, lineno) + except SyntaxWarning: + err = SyntaxError(msg) + err.filename = filename + err.lineno = lineno + raise err + class Scope: localsfullyknown = True # XXX how much information do I need about each name? @@ -355,6 +364,15 @@ def visitGlobal(self, node, scope): for name in node.names: + namescope = scope.check_name(name) + if namescope == SC_LOCAL: + issue_warning("name '%s' is assigned to before " + "global declaration" %(name,), + node.filename, node.lineno) + elif namescope != SC_GLOBAL and name in scope.uses: + issue_warning("name '%s' is used prior " + "to global declaration" %(name,), + node.filename, node.lineno) scope.add_global(name) def visitAssign(self, node, scope): From cfbolz at codespeak.net Sat Aug 27 11:18:27 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 11:18:27 +0200 (CEST) Subject: [pypy-svn] r16713 - pypy/release/0.7.x/pypy/module/posix/test Message-ID: <20050827091827.0C6DF27B5B@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 11:18:26 2005 New Revision: 16713 Added: pypy/release/0.7.x/pypy/module/posix/test/test_posix_libfile.py Log: test for os.fdopen that uses libfile Added: pypy/release/0.7.x/pypy/module/posix/test/test_posix_libfile.py ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/module/posix/test/test_posix_libfile.py Sat Aug 27 11:18:26 2005 @@ -0,0 +1,25 @@ +from pypy.objspace.std import StdObjSpace +from pypy.tool.udir import udir +import os + +def setup_module(mod): + mod.space = StdObjSpace(usemodules=['posix'], uselibfile=True) + mod.path = udir.join('posixtestfile.txt') + mod.path.write("this is a test") + +class AppTestPosix: + def setup_class(cls): + cls.space = space + cls.w_posix = space.appexec([], "(): import %s as m ; return m" % os.name) + cls.w_path = space.wrap(str(path)) + + def test_posix_is_pypy_s(self): + assert self.posix.__file__ + + def test_fdopen(self): + path = self.path + posix = self.posix + fd = posix.open(path, posix.O_RDONLY, 0777) + f = posix.fdopen(fd, "r") + result = f.read() + assert result == "this is a test" From ludal at codespeak.net Sat Aug 27 11:42:28 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 27 Aug 2005 11:42:28 +0200 (CEST) Subject: [pypy-svn] r16714 - pypy/release/0.7.x/lib-python Message-ID: <20050827094228.6F4D227B5B@code1.codespeak.net> Author: ludal Date: Sat Aug 27 11:42:26 2005 New Revision: 16714 Modified: pypy/release/0.7.x/lib-python/failure_list.txt Log: - more explanations Modified: pypy/release/0.7.x/lib-python/failure_list.txt ============================================================================== --- pypy/release/0.7.x/lib-python/failure_list.txt (original) +++ pypy/release/0.7.x/lib-python/failure_list.txt Sat Aug 27 11:42:26 2005 @@ -32,17 +32,36 @@ could be fixed, maybe (being worked on) test_compile - test_exec_with_general_mapping_for_locals should be modified - other tests are minor stuff that seem basically fixable, mostly - missing SyntaxErrors + - test_exec_with_general_mapping_for_locals has been modified to expect + a NameError for global lookup failure with a non standard dictionnary + PyPy doesn't translate KeyError to NameError for the global case but it + does it correctly for local + - test_for_distinct_code_objects works with pypy on top of python2.4 but not + on top of python2.3 this is because code objects differing only + by line number are equal on 2.3 and different on 2.4. This test is not worth + fixing. Pypy's own PyCode objects behave correctly and this is what we use both + for _stable and ast compilers + - test_unary_minus fails on top of 2.3 with stable compiler because it uses c-python eval + and the tests checks that eval("0xffffffff") returns 2*MAXINT and not -1 +test_generators + all tests that do not depend on weakrefs pass + test_traceback + - test_caret : fails because we don't include line text into the syntax error. needs a bit of + refactoring of the link between parser and transformer to make it work + - test_nocaret : it's testing an obscure case that basicaly returns a syntax error with 3 parameters (no positional info) + it even as a special if not_jython to pass on jython + test_future + to be investigated... + test_genexps - some SyntaxErrors don't come with a lineno attached, - but ideally we should always produce them. - A bug in test_genexps is being worked on (assignment to genexps). - + three failures because of different error messages along the lines of: + 'can't assign to genexpr' instead of 'assignement to genexpr ...' + 'division by zero' instead of 'division or modulo by zero' + the other failures are due to missing weakref support + test_trace Fails because of our compiler generating different linenumber information than CPythons. From hpk at codespeak.net Sat Aug 27 11:49:24 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 11:49:24 +0200 (CEST) Subject: [pypy-svn] r16717 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827094924.0091E27B5B@code1.codespeak.net> Author: hpk Date: Sat Aug 27 11:49:24 2005 New Revision: 16717 Modified: pypy/release/0.7.x/pypy/doc/index.txt Log: link to relative LICENSE file Modified: pypy/release/0.7.x/pypy/doc/index.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/index.txt (original) +++ pypy/release/0.7.x/pypy/doc/index.txt Sat Aug 27 11:49:24 2005 @@ -39,7 +39,7 @@ .. _`FAQ`: faq.html .. _parser: parser.html .. _`talks and related projects`: extradoc.html -.. _`license`: http://codespeak.net/svn/pypy/dist/LICENSE +.. _`license`: ../../LICENSE .. _`compliance test status`: http://codespeak.net/~hpk/pypy-testresult/ .. _`PyPy statistics`: http://codespeak.net/~hpk/pypy-stat/ .. _`object spaces`: objspace.html From arigo at codespeak.net Sat Aug 27 11:52:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 11:52:43 +0200 (CEST) Subject: [pypy-svn] r16718 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050827095243.99AAF27B5B@code1.codespeak.net> Author: arigo Date: Sat Aug 27 11:52:41 2005 New Revision: 16718 Modified: pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py pypy/release/0.7.x/pypy/translator/goal/app_main.py pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Log: issue127 testing Ported (bits of) the command-line parsing and sys.*hook support to app_main, which is used as the app-level entry point for the translated PyPy. Obscure hack to push the translation options into an app-level dict, 'sys.pypy_translation_info'. Modified: pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py Sat Aug 27 11:52:41 2005 @@ -1,3 +1,6 @@ print '--- beginning of app_example.py ---' print 6*7 print '--- end of app_example.py ---' + +import sys +print sys.pypy_translation_info Modified: pypy/release/0.7.x/pypy/translator/goal/app_main.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/app_main.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/app_main.py Sat Aug 27 11:52:41 2005 @@ -1,11 +1,162 @@ # App-level version of py.py. -# XXX very incomplete! Blindly runs the file named as first argument. -# No option checking, no interactive console, no fancy hooks. +# XXX this is probably still incomplete. +""" +options: + -i inspect interactively after running script + -O dummy optimization flag for compatibility with C Python + -c CMD program passed in as CMD (terminates option list) + -h, --help show this help message and exit + --version print the PyPy version + --info print translation information about this PyPy executable +""" + +import sys + +originalexcepthook = sys.__excepthook__ + +def run_toplevel(f, *fargs, **fkwds): + """Calls f() and handle all OperationErrors. + Intended use is to run the main program or one interactive statement. + run_protected() handles details like forwarding exceptions to + sys.excepthook(), catching SystemExit, printing a newline after + sys.stdout if needed, etc. + """ + try: + # run it + f(*fargs, **fkwds) + + # we arrive here if no exception is raised. stdout cosmetics... + try: + stdout = sys.stdout + softspace = stdout.softspace + except AttributeError: + pass + # Don't crash if user defined stdout doesn't have softspace + else: + if softspace: + stdout.write('\n') + + except SystemExit, e: + # exit if we catch a w_SystemExit + exitcode = e.code + if exitcode is None: + exitcode = 0 + else: + try: + exitcode = int(exitcode) + except: + # not an integer: print it to stderr + try: + stderr = sys.stderr + except AttributeError: + pass # too bad + else: + print >> stderr, exitcode + exitcode = 1 + raise SystemExit(exitcode) + + except: + etype, evalue, etraceback = sys.exc_info() + try: + # XXX extra debugging info in case the code below goes very wrong + # XXX (temporary) + if hasattr(sys, 'stderr'): + print >> sys.stderr, "debug: exception-type: ", etype.__name__ + print >> sys.stderr, "debug: exception-value:", str(evalue) + tbentry = etraceback + if tbentry: + while tbentry.tb_next: + tbentry = tbentry.tb_next + lineno = tbentry.tb_lineno + filename = tbentry.tb_frame.f_code.co_filename + print >> sys.stderr, "debug: exception-tb: %s:%d" % ( + filename, lineno) + + # set the sys.last_xxx attributes + sys.last_type = etype + sys.last_value = evalue + sys.last_traceback = etraceback + + # call sys.excepthook + hook = getattr(sys, 'excepthook', originalexcepthook) + hook(etype, evalue, etraceback) + return False # done + + except: + try: + stderr = sys.stderr + except AttributeError: + pass # too bad + else: + print >> stderr, 'Error calling sys.excepthook:' + originalexcepthook(*sys.exc_info()) + print >> stderr + print >> stderr, 'Original exception was:' + + # we only get here if sys.excepthook didn't do its job + originalexcepthook(etype, evalue, etraceback) + return False + + return True # success + +# ____________________________________________________________ +# Option parsing + +def print_info(): + try: + options = sys.pypy_translation_info + except AttributeError: + print >> sys.stderr, 'no translation information found' + else: + optitems = options.keys() + optitems.sort() + for name, value in optitems: + print ' %25s: %s' % (name, value) + +def print_help(): + print 'usage: %s [options]' % (sys.executable,) + print __doc__ + +def print_error(msg): + print >> sys.stderr, msg + print >> sys.stderr, 'usage: %s [options]' % (sys.executable,) + print >> sys.stderr, 'Try `%s -h` for more information.' % (sys.executable,) + +# ____________________________________________________________ +# Main entry point def entry_point(executable, argv): - import sys sys.executable = executable - sys.argv = argv + go_interactive = False + i = 0 + while i < len(argv): + arg = argv[i] + if not arg.startswith('-'): + break + if arg == '-i': + go_interactive = True + elif arg == '-c': + if i >= len(argv)-1: + print_error('Argument expected for the -c option') + return 2 + break + elif arg == '-O': + pass + elif arg == '--version': + print sys.version + return 0 + elif arg == '--info': + print_info() + return 0 + elif arg == '-h' or arg == '--help': + print_help() + return 0 + else: + print_error('unrecognized option %r' % (arg,)) + return 2 + i += 1 + sys.argv = argv[i:] + # with PyPy in top of CPython we can only have around 100 # but we need more in the translated PyPy for the compiler package sys.setrecursionlimit(5000) @@ -14,32 +165,29 @@ sys.modules['__main__'] = mainmodule try: - if argv: - execfile(sys.argv[0], mainmodule.__dict__) + if sys.argv: + if sys.argv[0] == '-c': + cmd = sys.argv.pop(1) + def run_it(): + exec cmd in mainmodule.__dict__ + run_toplevel(run_it) + else: + run_toplevel(execfile, sys.argv[0], mainmodule.__dict__) else: - print >> sys.stderr, "importing code" + go_interactive = True + if go_interactive: + print >> sys.stderr, "debug: importing code" import code - print >> sys.stderr, "calling code.interact()" - code.interact(local=mainmodule.__dict__) - except: - excinfo = sys.exc_info() - typ, val, tb = excinfo - print >> sys.stderr, "exception-type:", typ.__name__ - print >> sys.stderr, "exception-value:", str(val) - # print short tracebacks filename:lineno - tbentry = tb - while tbentry: - lineno = tbentry.tb_lineno - filename = tbentry.tb_frame.f_code.co_filename - print >>sys.stderr, " %s:%d" %(filename, lineno) - tbentry = tbentry.tb_next - # then take forever trying to print a traceback ... - #sys.excepthook(typ, val, tb) - return 1 + print >> sys.stderr, "debug: calling code.interact()" + run_toplevel(code.interact, local=mainmodule.__dict__) + except SystemExit, e: + return e.exitcode else: return 0 if __name__ == '__main__': + # obscure! try removing the following line, see how it crashes, and + # guess why... + ImStillAroundDontForgetMe = sys.modules['__main__'] # debugging only - import sys - sys.exit(entry_point(sys.argv[1:])) + sys.exit(entry_point(sys.argv[0], sys.argv[1:])) Modified: pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Sat Aug 27 11:52:41 2005 @@ -46,6 +46,15 @@ def target(geninterp=True): global space, w_entry_point + + # obscure hack to stuff the translation options into the translated PyPy + import __main__, pypy.module.sys + options = {} + for key, value in __main__.options.items(): + options[key.lstrip('-')] = value + wrapstr = 'space.wrap(%r)' % (options,) + pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] = wrapstr + # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None space = StdObjSpace(nofaking=True, From arigo at codespeak.net Sat Aug 27 12:14:41 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 12:14:41 +0200 (CEST) Subject: [pypy-svn] r16720 - in pypy/release/0.7.x/pypy/objspace: . test Message-ID: <20050827101441.3741927B56@code1.codespeak.net> Author: arigo Date: Sat Aug 27 12:14:37 2005 New Revision: 16720 Modified: pypy/release/0.7.x/pypy/objspace/descroperation.py pypy/release/0.7.x/pypy/objspace/test/test_descroperation.py Log: Fix and test for an obscure corner case exposed by CPython's test_builtin. Modified: pypy/release/0.7.x/pypy/objspace/descroperation.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/descroperation.py (original) +++ pypy/release/0.7.x/pypy/objspace/descroperation.py Sat Aug 27 12:14:37 2005 @@ -37,7 +37,10 @@ return w_dict = w_obj.getdict() if w_dict is not None: - space.setitem(w_dict, w_name, w_value) + # note: don't use w_name as a key in w_dict directly -- the expected + # result of setattr() is that it never stores subclasses of 'str' + # in the __dict__ + space.setitem(w_dict, space.wrap(name), w_value) return raiseattrerror(space, w_obj, name, w_descr) Modified: pypy/release/0.7.x/pypy/objspace/test/test_descroperation.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/test/test_descroperation.py (original) +++ pypy/release/0.7.x/pypy/objspace/test/test_descroperation.py Sat Aug 27 12:14:37 2005 @@ -181,3 +181,13 @@ def __nonzero__(self): return myint(1) raises(TypeError, "not X()") + + def test_string_subclass(self): + class S(str): + def __hash__(self): + return 123 + s = S("abc") + setattr(s, s, s) + assert len(s.__dict__) == 1 + assert type(s.__dict__.keys()[0]) is str # don't store S keys + assert s.abc is s From cfbolz at codespeak.net Sat Aug 27 12:29:35 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 12:29:35 +0200 (CEST) Subject: [pypy-svn] r16724 - pypy/release/0.7.x/pypy/rpython/module/test Message-ID: <20050827102935.24A0927B56@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 12:29:34 2005 New Revision: 16724 Modified: pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py Log: a small test for os.unsetenv Modified: pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py Sat Aug 27 12:29:34 2005 @@ -19,7 +19,6 @@ os.unlink(filename) - def test_getcwd(): data = ll_os_getcwd() assert from_rstr(data) == os.getcwd() @@ -36,16 +35,25 @@ assert file(filename).read().strip() == '2' os.unlink(filename) -def test_putenv(): +def test_putenv_unsetenv(): filename = str(udir.join('test_putenv.txt')) arg = to_rstr('abcdefgh=12345678') ll_os_putenv(arg) cmd = '''python -c "import os; print os.environ['abcdefgh']" > %s''' % filename os.system(cmd) - assert file(filename).read().strip() == '12345678' + f = file(filename) + result = f.read().strip() + assert result == '12345678' + f.close() + os.unlink(filename) + ll_os_unsetenv(to_rstr("abcdefgh")) + cmd = '''python -c "import os; print repr(os.getenv('abcdefgh'))" > %s''' % filename + os.system(cmd) + f = file(filename) + result = f.read().strip() + assert result == 'None' + f.close() os.unlink(filename) - -# XXX missing test for unsetenv, please do this on Linux def test_environ(): count = 0 From hpk at codespeak.net Sat Aug 27 12:31:51 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 12:31:51 +0200 (CEST) Subject: [pypy-svn] r16725 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827103151.9DD6A27B56@code1.codespeak.net> Author: hpk Date: Sat Aug 27 12:31:51 2005 New Revision: 16725 Modified: pypy/release/0.7.x/pypy/doc/_ref.txt pypy/release/0.7.x/pypy/doc/translation.txt Log: rengerated refs and cleaned up refs in translation.txt (python tool/makeref.py is the ref-regen) Modified: pypy/release/0.7.x/pypy/doc/_ref.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/_ref.txt (original) +++ pypy/release/0.7.x/pypy/doc/_ref.txt Sat Aug 27 12:31:51 2005 @@ -1,13 +1,13 @@ .. _`demo/`: ../../demo .. _`lib-python/`: ../../lib-python .. _`lib-python/2.4.1/dis.py`: ../../lib-python/2.4.1/dis.py -.. _`annotation/`: -.. _`pypy/annotation`: ../../pypy/annotation +.. _`pypy/annotation`: +.. _`annotation/`: ../../pypy/annotation .. _`annotation/binaryop.py`: ../../pypy/annotation/binaryop.py .. _`doc/`: ../../pypy/doc .. _`doc/revreport/`: ../../pypy/doc/revreport -.. _`interpreter/`: -.. _`pypy/interpreter`: ../../pypy/interpreter +.. _`pypy/interpreter`: +.. _`interpreter/`: ../../pypy/interpreter .. _`pypy/interpreter/argument.py`: ../../pypy/interpreter/argument.py .. _`pypy/interpreter/function.py`: ../../pypy/interpreter/function.py .. _`pypy/interpreter/gateway.py`: ../../pypy/interpreter/gateway.py @@ -28,16 +28,16 @@ .. _`module/parser/`: ../../pypy/module/parser .. _`module/recparser/`: ../../pypy/module/recparser .. _`module/sys/`: ../../pypy/module/sys -.. _`objspace/`: -.. _`pypy/objspace`: ../../pypy/objspace +.. _`pypy/objspace`: +.. _`objspace/`: ../../pypy/objspace .. _`objspace/flow/`: ../../pypy/objspace/flow -.. _`objspace/std/`: -.. _`pypy/objspace/std`: ../../pypy/objspace/std +.. _`pypy/objspace/std`: +.. _`objspace/std/`: ../../pypy/objspace/std .. _`objspace/thunk.py`: ../../pypy/objspace/thunk.py .. _`objspace/trace.py`: .. _`pypy/objspace/trace.py`: ../../pypy/objspace/trace.py -.. _`rpython/`: -.. _`pypy/rpython`: ../../pypy/rpython +.. _`pypy/rpython`: +.. _`rpython/`: ../../pypy/rpython .. _`pypy/rpython/extfunctable.py`: ../../pypy/rpython/extfunctable.py .. _`pypy/rpython/lltype.py`: .. _`rpython/lltype.py`: ../../pypy/rpython/lltype.py @@ -53,8 +53,8 @@ .. _`tool/`: ../../pypy/tool .. _`tool/pytest/`: ../../pypy/tool/pytest .. _`tool/tb_server/`: ../../pypy/tool/tb_server -.. _`translator/`: -.. _`pypy/translator`: ../../pypy/translator +.. _`pypy/translator`: +.. _`translator/`: ../../pypy/translator .. _`pypy/translator/annrpython.py`: ../../pypy/translator/annrpython.py .. _`translator/c/`: ../../pypy/translator/c .. _`pypy/translator/c/extfunc.py`: ../../pypy/translator/c/extfunc.py Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Sat Aug 27 12:31:51 2005 @@ -51,13 +51,13 @@ 6. This lower-level source file is compiled to produce an executable. .. _`SSA`: http://en.wikipedia.org/wiki/Static_single_assignment_form -.. _`translator.py`: http://codespeak.net/svn/pypy/dist/pypy/translator/translator.py +.. _`translator.py`: http://codespeak.net/pypy/dist/pypy/translator/translator.py .. _`play around`: getting-started.html#trying-out-the-translator .. _`Flow Object Space`: objspace.html#the-flow-object-space .. _`control flow graph`: objspace.html#the-flow-model -.. _`Common Lisp`: http://codespeak.net/svn/pypy/dist/pypy/translator/gencl.py -.. _Pyrex: http://codespeak.net/svn/pypy/dist/pypy/translator/pyrex/genpyrex.py -.. _Java: http://codespeak.net/svn/pypy/dist/pypy/translator/java/ +.. _`Common Lisp`: http://codespeak.net/pypy/dist/pypy/translator/gencl.py +.. _Pyrex: http://codespeak.net/pypy/dist/pypy/translator/pyrex/genpyrex.py +.. _Java: http://codespeak.net/pypy/dist/pypy/translator/java/ .. _graph: image/translation.pdf @@ -438,7 +438,7 @@ The RPython Typer ================= -http://codespeak.net/svn/pypy/dist/pypy/rpython/ +http://codespeak.net/pypy/dist/pypy/rpython/ Overview @@ -955,15 +955,13 @@ interpret_raises(IndexError, raise_exception, [42]) interpret_raises(ValueError, raise_exception, [43]) -.. _`pypy/rpython/test/test_llinterp.py`: ../rpython/test/test_llinterp.py - .. _C: .. _GenC: The C Back-End ============== -http://codespeak.net/svn/pypy/dist/pypy/translator/genc/ +http://codespeak.net/pypy/dist/pypy/translator/genc/ Overview @@ -987,7 +985,7 @@ The LLVM Back-End ================= -http://codespeak.net/svn/pypy/dist/pypy/translator/llvm/ +http://codespeak.net/pypy/dist/pypy/translator/llvm/ XXX to be written @@ -997,7 +995,7 @@ The Interplevel Back-End ======================== -http://codespeak.net/svn/pypy/dist/pypy/translator/geninterplevel.py +http://codespeak.net/pypy/dist/pypy/translator/geninterplevel.py Motivation ---------- @@ -1014,8 +1012,8 @@ any longer to execute this code. .. _`application-level`: architecture.html#app-preferable -.. _exceptions: http://codespeak.net/svn/pypy/dist/pypy/lib/_exceptions.py -.. _oldstyle: http://codespeak.net/svn/pypy/dist/pypy/lib/_classobj.py +.. _exceptions: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py +.. _oldstyle: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py Examples are exceptions_ and oldstyle_ classes. They are needed in a very early phase of bootstrapping StdObjspace, but @@ -1040,7 +1038,7 @@ Example ------- -.. _implementation: http://codespeak.net/svn/pypy/dist/pypy/translator/geninterplevel.py +.. _implementation: http://codespeak.net/pypy/dist/pypy/translator/geninterplevel.py Let's try the little example from above_. You might want to look at the flowgraph that it produces. Here, we directly run the Python translation @@ -1178,8 +1176,8 @@ Interplevel Snippets in the Sources ----------------------------------- -.. _`_exceptions.py`: http://codespeak.net/svn/pypy/dist/pypy/lib/_exceptions.py -.. _`_classobj.py`: http://codespeak.net/svn/pypy/dist/pypy/lib/_classobj.py +.. _`_exceptions.py`: http://codespeak.net/pypy/dist/pypy/lib/_exceptions.py +.. _`_classobj.py`: http://codespeak.net/pypy/dist/pypy/lib/_classobj.py Code written in application space can consist of complete files to be translated (`_exceptions.py`_, `_classobj.py`_), or they @@ -1248,11 +1246,6 @@ ``module.ll_function``. The backend is supposed to replace calls to functions to ``module.ll_function`` by whatever code it finds appropriate. -.. _`pypy/rpython/extfunctable.py`: ../rpython/extfunctable.py -.. _`pypy/rpython/module/`: ../rpython/module - - - Implementating low level replacement functions in Python --------------------------------------------------------- @@ -1297,9 +1290,6 @@ ``predeclare_utility_functions`` are automatically made accessible under their name in C. -.. _`pypy/translator/c/extfunc.py`: ../translator/c/extfunc.py -.. _`pypy/translator/c/src/`: ../translator/c/src/ - Testing ------- @@ -1314,10 +1304,6 @@ backend code is correct. For the C backend this is done in `pypy/translator/c/test/test_extfunc.py`_. -.. _`pypy/rpython/module/test`: ../rpython/module/test/ -.. _`pypy/translator/c/test/test_extfunc.py`: ../translator/c/test/test_extfunc.py - - Example ------- @@ -1385,8 +1371,6 @@ .. _`mixed posix module`: ../module/posix/ -.. _`pypy/rpython/module/ll_os.py`: ../rpython/module/ll_os.py -.. _`pypy/translator/c/src/ll_os.h`: ../translator/c/src/ll_os.h .. include:: _ref.txt From arigo at codespeak.net Sat Aug 27 12:33:03 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 12:33:03 +0200 (CEST) Subject: [pypy-svn] r16726 - pypy/release/0.7.x/pypy/translator/c/src Message-ID: <20050827103303.767BB27B56@code1.codespeak.net> Author: arigo Date: Sat Aug 27 12:33:03 2005 New Revision: 16726 Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Log: Added a newline at the end of the file (gcc gives a warning). Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/src/ll_os.h (original) +++ pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Sat Aug 27 12:33:03 2005 @@ -248,4 +248,4 @@ rs = RPyString_FromString(s); } return rs; -} \ No newline at end of file +} From ericvrp at codespeak.net Sat Aug 27 12:34:00 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 12:34:00 +0200 (CEST) Subject: [pypy-svn] r16727 - pypy/release/0.7.x/pypy/translator/llvm/test Message-ID: <20050827103400.7820A27B56@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 12:33:59 2005 New Revision: 16727 Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py Log: moving to other test-file Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_genllvm1.py Sat Aug 27 12:33:59 2005 @@ -54,16 +54,6 @@ assert shl(42,2) == llvmsnippet.shiftleft(42, 2) assert shr(42,2) == llvmsnippet.shiftright(42,2) - def test_shift_with_overflow(self): - py.test.skip("overflow not working yet") - shl = compile_function(llvmsnippet.shiftleft, [int, int]) - shr = compile_function(llvmsnippet.shiftright, [int, int]) - for i in [1, 2, 3, 100000, 2000000, sys.maxint - 1]: - for j in [1, 2, 3, 100000, 2000000, sys.maxint - 1]: - assert shl(i, j) == i << j - assert shr(i, j) == i >> j - - class TestFloat(object): def test_float_f1(self): f = compile_function(llvmsnippet.float_f1, [float]) From nik at codespeak.net Sat Aug 27 12:46:54 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 27 Aug 2005 12:46:54 +0200 (CEST) Subject: [pypy-svn] r16728 - pypy/dist/pypy/module/_sre/test Message-ID: <20050827104654.AF61827B56@code1.codespeak.net> Author: nik Date: Sat Aug 27 12:46:53 2005 New Revision: 16728 Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py Log: added failing test uncovered by compliancy tests. Modified: pypy/dist/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_app_sre.py Sat Aug 27 12:46:53 2005 @@ -451,6 +451,13 @@ assert re.search(r"b(? Author: nik Date: Sat Aug 27 12:48:19 2005 New Revision: 16729 Removed: pypy/dist/pypy/module/_sre/app_info.py Modified: pypy/dist/pypy/module/_sre/__init__.py pypy/dist/pypy/module/_sre/interp_sre.py Log: integrated app_info into interp_sre. fixed annotation issues. Modified: pypy/dist/pypy/module/_sre/__init__.py ============================================================================== --- pypy/dist/pypy/module/_sre/__init__.py (original) +++ pypy/dist/pypy/module/_sre/__init__.py Sat Aug 27 12:48:19 2005 @@ -9,15 +9,15 @@ """ appleveldefs = { - 'CODESIZE': 'app_info.CODESIZE', - 'MAGIC': 'app_info.MAGIC', - 'copyright': 'app_info.copyright', - 'getcodesize': 'app_info.getcodesize', 'compile': 'app_sre.compile', } interpleveldefs = { + 'CODESIZE': 'space.wrap(interp_sre.CODESIZE)', + 'MAGIC': 'space.wrap(interp_sre.MAGIC)', + 'copyright': 'space.wrap(interp_sre.copyright)', 'getlower': 'interp_sre.w_getlower', + 'getcodesize': 'interp_sre.w_getcodesize', '_State': 'interp_sre.make_state', '_match': 'interp_sre.w_match', '_search': 'interp_sre.w_search', Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Sat Aug 27 12:48:19 2005 @@ -1,14 +1,28 @@ -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -# XXX is it allowed to import app-level module like this? -from pypy.module._sre.app_info import CODESIZE +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app - import sys -BIG_ENDIAN = sys.byteorder == "big" -#### Exposed functions +#### Constants and exposed functions + +# Identifying as _sre from Python 2.3 or 2.4 +MAGIC = 20031017 + +# In _sre.c this is bytesize of the code word type of the C implementation. +# There it's 2 for normal Python builds and more for wide unicode builds (large +# enough to hold a 32-bit UCS-4 encoded character). Since here in pure Python +# we only see re bytecodes as Python longs, we shouldn't have to care about the +# codesize. But sre_compile will compile some stuff differently depending on the +# codesize (e.g., charsets). +if sys.maxunicode == 65535: + CODESIZE = 2 +else: + CODESIZE = 4 + +copyright = "_sre.py 2.4 Copyright 2005 by Nik Haldimann" + +BIG_ENDIAN = sys.byteorder == "big" # XXX can we import those safely from sre_constants? SRE_INFO_PREFIX = 1 @@ -31,6 +45,9 @@ else: return char_ord +def w_getcodesize(space): + return space.wrap(CODESIZE) + #### Core classes def make_state(space, w_string, w_start, w_end, w_flags): @@ -106,30 +123,31 @@ def lower(self, char_ord): return getlower(self.space, char_ord, self.flags) -def interp_attrproperty_int(name, cls): - "NOT_RPYTHON: initialization-time only" - def fget(space, obj): - return space.wrap(getattr(obj, name)) - def fset(space, obj, w_value): - setattr(obj, name, space.int_w(w_value)) - return GetSetProperty(fget, fset, cls=cls) - -def interp_attrproperty_obj_w(name, cls): - "NOT_RPYTHON: initialization-time only" - def fget(space, obj): - return getattr(obj, name) - def fset(space, obj, w_value): - setattr(obj, name, w_value) - return GetSetProperty(fget, fset, cls=cls) + # Accessors for the typedef + + def fget_start(space, self): + return space.wrap(self.start) + + def fset_start(space, self, w_value): + self.start = space.int_w(w_value) + + def fget_string_position(space, self): + return space.wrap(self.string_position) + + def fset_string_position(space, self, w_value): + self.start = space.int_w(w_value) + +getset_start = GetSetProperty(W_State.fget_start, W_State.fset_start, cls=W_State) +getset_string_position = GetSetProperty(W_State.fget_string_position, + W_State.fset_string_position, cls=W_State) W_State.typedef = TypeDef("W_State", - string = interp_attrproperty_obj_w("w_string", W_State), - start = interp_attrproperty_int("start", W_State), - end = interp_attrproperty_int("end", W_State), - string_position = interp_attrproperty_int("string_position", W_State), + string = interp_attrproperty_w("w_string", W_State), + start = getset_start, + end = interp_attrproperty("end", W_State), + string_position = getset_string_position, pos = interp_attrproperty("pos", W_State), lastindex = interp_attrproperty("lastindex", W_State), - repeat = interp_attrproperty_obj_w("w_repeat", W_State), reset = interp2app(W_State.w_reset), create_regs = interp2app(W_State.w_create_regs), ) @@ -227,6 +245,7 @@ #### Main opcode dispatch loop def w_search(space, w_state, w_pattern_codes): + assert isinstance(w_state, W_State) pattern_codes = [space.int_w(code) for code in space.unpackiterable(w_pattern_codes)] return space.newbool(search(space, w_state, pattern_codes)) @@ -289,6 +308,7 @@ return False def w_match(space, w_state, w_pattern_codes): + assert isinstance(w_state, W_State) pattern_codes = [space.int_w(code) for code in space.unpackiterable(w_pattern_codes)] return space.newbool(match(space, w_state, pattern_codes)) From cfbolz at codespeak.net Sat Aug 27 12:49:21 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 12:49:21 +0200 (CEST) Subject: [pypy-svn] r16730 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827104921.0A67227B56@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 12:49:20 2005 New Revision: 16730 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: added the text that you see after translation of PyPy was successful Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 12:49:20 2005 @@ -386,7 +386,7 @@ compiled and executed. translating the PyPy interpreter -++++++++++++++++++++++++++++++++ +-------------------------------- Not for the faint of heart nor the owner of a very old machine: you can translate the whole of PyPy to low level C code. This is the largest and @@ -400,18 +400,34 @@ ``-t_lowmem`` With this option the whole process should be runnable on a machine with 512Mb of RAM. If the translation is finished running and after you closed the graph you will be greeted by the friendly prompt of a PyPy -executable that is not running on top of CPython any more. +executable that is not running on top of CPython any more:: -Moving around in the resulting flow graph is difficult because of the sheer -size of the result. For this reason, the debugger prompt you get at -the end has been enhanced with commands to facilitate locating functions and -classes. Type ``help graphs`` for a list of the new commands. Help is also -available on each of these new commands. + Running! + debug: entry point starting + debug: argv -> ./pypy-c + importing code + calling code.interact() + Python 2.4.1 (pypy 0.7.0 build) on linux2 + Type "help", "copyright", "credits" or "license" for more information. + (InteractiveConsole) + >>>> 1 + 1 + 2 + >>>> + +If you exit the interpreter you get a pygame window with all the flowgraphs +plus a pdb prompt. Moving around in the resulting flow graph is difficult +because of the sheer size of the result. For this reason, the debugger prompt +you get at the end has been enhanced with commands to facilitate locating +functions and classes. Type ``help graphs`` for a list of the new commands. +Help is also available on each of these new commands. The ``translate_pypy`` script itself takes a number of options controlling what to translate and how. See ``translate_pypy.py -h``. Some of the more interesting options are: + * ``-text``: don't show the flowgraph after the translation is done. This + is useful if you don't have pygame installed. + * ``-llvm``: produce code for LLVM_ instead of for C. One of the biggest things not working there is threading. @@ -419,7 +435,8 @@ our own reference counting implementation. -Try out:: +You can also use the translate_pypy.py script to try out several smaller +programs, e.g. a slightly changed version of Pystone:: cd pypy/translator/goal python translate_pypy.py targetrpystone @@ -428,6 +445,7 @@ python translate_pypy.py targetrpystone2 + .. _`start reading sources`: Where to start reading the sources From arigo at codespeak.net Sat Aug 27 12:49:24 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 12:49:24 +0200 (CEST) Subject: [pypy-svn] r16731 - pypy/release/0.7.x/pypy/translator/c/src Message-ID: <20050827104924.017BA27B5D@code1.codespeak.net> Author: arigo Date: Sat Aug 27 12:49:23 2005 New Revision: 16731 Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_thread.h Log: Trying to work around the last gcc warning. Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_thread.h ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/src/ll_thread.h (original) +++ pypy/release/0.7.x/pypy/translator/c/src/ll_thread.h Sat Aug 27 12:49:23 2005 @@ -36,10 +36,10 @@ } } -long LL_thread_start(void (*func)(void *), void *arg) +long LL_thread_start(void *func, void *arg) { /* XXX func() should not raise exceptions */ - long ident = RPyThreadStart(func, arg); + long ident = RPyThreadStart((void (*)(void*)) func, arg); if (ident == -1) RPyRaiseSimpleException(PyExc_thread_error, "can't start new thread"); From arigo at codespeak.net Sat Aug 27 12:51:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 12:51:02 +0200 (CEST) Subject: [pypy-svn] r16734 - in pypy/release/0.7.x/pypy: interpreter interpreter/test lib Message-ID: <20050827105102.CC47027B56@code1.codespeak.net> Author: arigo Date: Sat Aug 27 12:51:00 2005 New Revision: 16734 Modified: pypy/release/0.7.x/pypy/interpreter/pyopcode.py pypy/release/0.7.x/pypy/interpreter/test/test_exec.py pypy/release/0.7.x/pypy/lib/operator.py Log: Fix the 'exec' statement refusing general mappings as globals and locals. Should help make CPython's test_builtin more happy. Modified: pypy/release/0.7.x/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyopcode.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyopcode.py Sat Aug 27 12:51:00 2005 @@ -874,14 +874,12 @@ locals = globals if not isinstance(globals, dict): - if not (hasattr(globals, '__getitem__') and - hasattr(globals, 'keys')): + if hasattr(globals, '__getitem__'): raise TypeError("exec: arg 2 must be a dictionary or None") if '__builtins__' not in globals: globals['__builtins__'] = builtin if not isinstance(locals, dict): - if not (hasattr(locals, '__getitem__') and - hasattr(locals, 'keys')): + if hasattr(locals, '__getitem__'): raise TypeError("exec: arg 3 must be a dictionary or None") if not isinstance(prog, codetype): Modified: pypy/release/0.7.x/pypy/interpreter/test/test_exec.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/test/test_exec.py (original) +++ pypy/release/0.7.x/pypy/interpreter/test/test_exec.py Sat Aug 27 12:51:00 2005 @@ -174,3 +174,16 @@ d = {} exec "x=5 " in d assert d['x'] == 5 + + def test_mapping_as_locals(self): + class M(object): + def __getitem__(self, key): + return key + def __setitem__(self, key, value): + self.result[key] = value + m = M() + m.result = {} + exec "x=m" in {}, m + assert m.result == {'x': 'm'} + exec "y=n" in m # NOTE: this doesn't work in CPython 2.4 + assert m.result == {'x': 'm', 'y': 'n'} Modified: pypy/release/0.7.x/pypy/lib/operator.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/operator.py (original) +++ pypy/release/0.7.x/pypy/lib/operator.py Sat Aug 27 12:51:00 2005 @@ -101,6 +101,7 @@ # XXX the following is approximative def isMappingType(obj,): 'isMappingType(a) -- Return True if a has a mapping type, False otherwise.' + # XXX this is fragile and approximative anyway return hasattr(obj, '__getitem__') and hasattr(obj, 'keys') def isNumberType(obj,): 'isNumberType(a) -- Return True if a has a numeric type, False otherwise.' From arigo at codespeak.net Sat Aug 27 12:51:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 12:51:12 +0200 (CEST) Subject: [pypy-svn] r16735 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050827105112.9414027B59@code1.codespeak.net> Author: arigo Date: Sat Aug 27 12:51:11 2005 New Revision: 16735 Modified: pypy/release/0.7.x/pypy/translator/goal/app_main.py Log: Typo. Modified: pypy/release/0.7.x/pypy/translator/goal/app_main.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/app_main.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/app_main.py Sat Aug 27 12:51:11 2005 @@ -108,7 +108,7 @@ except AttributeError: print >> sys.stderr, 'no translation information found' else: - optitems = options.keys() + optitems = options.items() optitems.sort() for name, value in optitems: print ' %25s: %s' % (name, value) From pedronis at codespeak.net Sat Aug 27 12:56:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 27 Aug 2005 12:56:28 +0200 (CEST) Subject: [pypy-svn] r16736 - in pypy/release/0.7.x/pypy: interpreter module/posix module/recparser module/sys Message-ID: <20050827105628.841AC27B56@code1.codespeak.net> Author: pedronis Date: Sat Aug 27 12:56:25 2005 New Revision: 16736 Modified: pypy/release/0.7.x/pypy/interpreter/baseobjspace.py pypy/release/0.7.x/pypy/interpreter/mixedmodule.py pypy/release/0.7.x/pypy/module/posix/__init__.py pypy/release/0.7.x/pypy/module/recparser/__init__.py pypy/release/0.7.x/pypy/module/sys/__init__.py pypy/release/0.7.x/pypy/module/sys/state.py Log: moved all the logic to install both mixed and faked modules to baseobjspace now names like faked+_sre can be used in --usemodules option to force a faked module even if an app-level implementation is present under lib or a mixed module for the module is enabled by default. Modified: pypy/release/0.7.x/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/baseobjspace.py (original) +++ pypy/release/0.7.x/pypy/interpreter/baseobjspace.py Sat Aug 27 12:56:25 2005 @@ -145,16 +145,28 @@ def __repr__(self): return self.__class__.__name__ - def setbuiltinmodule(self, name, importname=None): + def setbuiltinmodule(self, importname, installed_builtin_modules=[]): """NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules""" - if importname is None: - importname = name - Module = __import__("pypy.module.%s" % importname, + import sys + + fullname = "pypy.module.%s" % importname + + Module = __import__(fullname, None, None, ["Module"]).Module + if Module.applevel_name is not None: + name = Module.applevel_name + else: + name = importname + + if name in installed_builtin_modules: + del sys.modules[fullname] + return None + w_name = self.wrap(name) w_mod = self.wrap(Module(self, w_name)) w_modules = self.sys.get('modules') self.setitem(w_modules, w_name, w_mod) + return name def getbuiltinmodule(self, name): w_name = self.wrap(name) @@ -163,20 +175,14 @@ # change this to influence which of our own # mixed modules should be used - def get_builtinmodule_list(self): + def get_builtinmodule_to_install(self): """NOT_RPYTHON""" try: return self._builtinmodule_list except AttributeError: pass - modules = ['sys', '__builtin__', 'exceptions', 'unicodedata', '_codecs', - 'array', 'marshal', 'errno', 'math'] - - if self.options.nofaking: - modules.append('posix') - modules.append('time') - modules.append('errno') + modules = ['sys', '__builtin__', 'exceptions'] # there also are the '_sre' and 'marshal' modules # but those currently cause translation problems. You can @@ -186,20 +192,37 @@ if name not in modules: modules.append(name) - # the returned builtinmodule_list contains tuples of - # names because some modules have a filesystem name - # that differs from the app-visible name (because you - # can specify implementation variants) - builtinmodule_list = [(x, None) for x in modules] - bml = builtinmodule_list - if ('posix', None) in bml: - bml[bml.index( ('posix', None) )] = (os.name, 'posix') + modules.extend(['unicodedata', '_codecs', + 'array', 'marshal', 'errno', 'math']) + + if self.options.nofaking: + modules.append('posix') + modules.append('time') + modules.append('errno') + if self.options.parser == "pypy": - builtinmodule_list.append(('parser', 'recparser')) - builtinmodule_list.append(('symbol', None)) - self._builtinmodule_list = builtinmodule_list + modules.append('recparser') + modules.append('symbol') + + import pypy + if not self.options.nofaking: + for modname in self.ALL_BUILTIN_MODULES: + if not (os.path.exists( + os.path.join(os.path.dirname(pypy.__file__), + 'lib', modname+'.py'))): + modules.append('faked+'+modname) + + self._builtinmodule_list = modules return self._builtinmodule_list + ALL_BUILTIN_MODULES = [ + 'posix', 'nt', 'os2', 'mac', 'ce', 'riscos', + 'math', 'array', 'select', + '_random', '_sre', 'time', '_socket', 'errno', + 'unicodedata', + 'parser', 'fcntl', '_codecs', 'binascii' + ] + def make_builtins(self): "NOT_RPYTHON: only for initializing the space." @@ -216,10 +239,8 @@ self.setitem(w_modules, w_name, w_builtin) self.setitem(self.builtin.w_dict, self.wrap('__builtins__'), w_builtin) - for modname, mixedname in self.get_builtinmodule_list(): - if modname not in ('sys', '__builtin__', 'exceptions'):##!!, 'marshal'): - self.setbuiltinmodule(modname, mixedname) - + installed_builtin_modules = ['sys', '__builtin__', 'exceptions'] # bootstrap ones + # 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'): @@ -227,11 +248,55 @@ #print "setitem: space instance %-20s into builtins" % name self.setitem(self.builtin.w_dict, self.wrap(name), value) + # install midex and faked modules and set builtin_module_names on sys + for mixedname in self.get_builtinmodule_to_install(): + if not mixedname.startswith('faked+'): + self.install_mixemodule(mixedname, installed_builtin_modules) + else: + modname = mixedname[6:] + self.install_faked_module(modname, installed_builtin_modules) + + installed_builtin_modules.sort() + w_builtin_module_names = self.newtuple( + [self.wrap(fn) for fn in installed_builtin_modules]) + + # force this value into the dict without unlazyfying everything + self.setitem(self.sys.w_dict, self.wrap('builtin_module_names'), + w_builtin_module_names) + + def install_mixemodule(self, mixedname, installed_builtin_modules): + """NOT_RPYTHON""" + if mixedname not in installed_builtin_modules: + modname = self.setbuiltinmodule(mixedname, installed_builtin_modules) + if modname: + installed_builtin_modules.append(modname) + + def load_cpython_module(self, modname): + "NOT_RPYTHON. Steal a module from CPython." + cpy_module = __import__(modname, {}, {}, ['*']) + return cpy_module + + def install_faked_module(self, modname, installed_builtin_modules): + """NOT_RPYTHON""" + if modname in installed_builtin_modules: + return + try: + module = self.load_cpython_module(modname) + except ImportError: + return + else: + w_modules = self.sys.get('modules') + self.setitem(w_modules, self.wrap(modname), self.wrap(module)) + installed_builtin_modules.append(modname) + def setup_builtin_modules(self): "NOT_RPYTHON: only for initializing the space." - for modname, mixedname in self.get_builtinmodule_list(): + from pypy.interpreter.module import Module + for w_modname in self.unpackiterable(self.sys.get('builtin_module_names')): + modname = self.unwrap(w_modname) mod = self.getbuiltinmodule(modname) - mod.setup_after_space_initialization() + if isinstance(mod, Module): + mod.setup_after_space_initialization() def initialize(self): """NOT_RPYTHON: Abstract method that should put some minimal Modified: pypy/release/0.7.x/pypy/interpreter/mixedmodule.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/mixedmodule.py (original) +++ pypy/release/0.7.x/pypy/interpreter/mixedmodule.py Sat Aug 27 12:56:25 2005 @@ -10,6 +10,8 @@ class MixedModule(Module): NOT_RPYTHON_ATTRIBUTES = ['loaders'] + + applevel_name = None def __init__(self, space, w_name): """ NOT_RPYTHON """ Modified: pypy/release/0.7.x/pypy/module/posix/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/posix/__init__.py Sat Aug 27 12:56:25 2005 @@ -10,6 +10,8 @@ disguised Unix interface). Refer to the library manual and corresponding Unix manual entries for more information on calls.""" + applevel_name = os.name + appleveldefs = { 'error' : 'app_posix.error', 'stat_result': 'app_posix.stat_result', Modified: pypy/release/0.7.x/pypy/module/recparser/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/recparser/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/recparser/__init__.py Sat Aug 27 12:56:25 2005 @@ -12,6 +12,7 @@ """The builtin parser module. """ + applevel_name = 'parser' appleveldefs = { 'ParserError' : 'app_class.ParserError', Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/sys/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/sys/__init__.py Sat Aug 27 12:56:25 2005 @@ -32,7 +32,7 @@ 'modules' : 'state.get(space).w_modules', 'argv' : 'state.get(space).w_argv', 'warnoptions' : 'state.get(space).w_warnoptions', - 'builtin_module_names' : 'state.get(space).w_builtin_module_names', + 'builtin_module_names' : 'state.w_None', 'pypy_getudir' : 'state.pypy_getudir', '_getframe' : 'vm._getframe', Modified: pypy/release/0.7.x/pypy/module/sys/state.py ============================================================================== --- pypy/release/0.7.x/pypy/module/sys/state.py (original) +++ pypy/release/0.7.x/pypy/module/sys/state.py Sat Aug 27 12:56:25 2005 @@ -6,61 +6,19 @@ import sys, os -def load_cpython_module(modname): - "NOT_RPYTHON. Steal a module from CPython." - cpy_module = __import__(modname, globals(), locals(), None) - return cpy_module - # ____________________________________________________________ # -ALL_BUILTIN_MODULES = [ - 'posix', 'nt', 'os2', 'mac', 'ce', 'riscos', - 'math', 'array', 'select', - '_random', '_sre', 'time', '_socket', 'errno', - 'unicodedata', - 'parser', 'fcntl', '_codecs', 'binascii' -] - class State: def __init__(self, space): self.space = space self.w_modules = space.newdict([]) - self.complete_builtinmodules() self.w_warnoptions = space.newlist([]) self.w_argv = space.newlist([]) self.setinitialpath(space) - def install_faked_module(self, modname): - space = self.space - try: - module = load_cpython_module(modname) - except ImportError: - return False - else: - space.setitem(self.w_modules, space.wrap(modname), - space.wrap(module)) - return True - - def complete_builtinmodules(self): - space = self.space - builtinmodule_list = self.space.get_builtinmodule_list() - builtinmodule_names = [name for name, mixedname in builtinmodule_list] - - if not space.options.nofaking: - for modname in ALL_BUILTIN_MODULES: - if modname not in builtinmodule_names: - if not (os.path.exists( - os.path.join(os.path.dirname(pypy.__file__), - 'lib', modname+'.py'))): - if self.install_faked_module(modname): - builtinmodule_names.append(modname) - builtinmodule_names.sort() - self.w_builtin_module_names = space.newtuple( - [space.wrap(fn) for fn in builtinmodule_names]) - def setinitialpath(self, space): # Initialize the default path from pypy.interpreter import autopath From arigo at codespeak.net Sat Aug 27 12:59:53 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 12:59:53 +0200 (CEST) Subject: [pypy-svn] r16737 - in pypy/release/0.7.x/pypy/module/__builtin__: . test Message-ID: <20050827105953.89EEF27B56@code1.codespeak.net> Author: arigo Date: Sat Aug 27 12:59:51 2005 New Revision: 16737 Modified: pypy/release/0.7.x/pypy/module/__builtin__/app_inspect.py pypy/release/0.7.x/pypy/module/__builtin__/test/test_builtin.py Log: Another corner case and fix for CPython's test_builtin. Modified: pypy/release/0.7.x/pypy/module/__builtin__/app_inspect.py ============================================================================== --- pypy/release/0.7.x/pypy/module/__builtin__/app_inspect.py (original) +++ pypy/release/0.7.x/pypy/module/__builtin__/app_inspect.py Sat Aug 27 12:59:51 2005 @@ -106,6 +106,8 @@ % len(args)) if len(args) == 0: local_names = _caller_locals().keys() # 2 stackframes away + if not isinstance(local_names, list): + raise TypeError("expected locals().keys() to be a list") local_names.sort() return local_names @@ -116,6 +118,8 @@ if isinstance(obj, types.ModuleType): try: result = obj.__dict__.keys() + if not isinstance(result, list): + raise TypeError("expected __dict__.keys() to be a list") result.sort() return result except AttributeError: Modified: pypy/release/0.7.x/pypy/module/__builtin__/test/test_builtin.py ============================================================================== --- pypy/release/0.7.x/pypy/module/__builtin__/test/test_builtin.py (original) +++ pypy/release/0.7.x/pypy/module/__builtin__/test/test_builtin.py Sat Aug 27 12:59:51 2005 @@ -58,6 +58,14 @@ b = 67 assert nosp(dir(X)) == ['a', 'b', 'c'] + def test_dir_in_broken_locals(self): + class C: + def __getitem__(self, item): + raise KeyError(item) + def keys(self): + return 'a' # not a list! + raises(TypeError, eval, "dir()", {}, C()) + def test_vars(self): def f(): return vars() From rxe at codespeak.net Sat Aug 27 13:05:59 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 27 Aug 2005 13:05:59 +0200 (CEST) Subject: [pypy-svn] r16739 - in pypy/release/0.7.x/pypy/translator/llvm: . module Message-ID: <20050827110559.F2E5327B56@code1.codespeak.net> Author: rxe Date: Sat Aug 27 13:05:58 2005 New Revision: 16739 Modified: pypy/release/0.7.x/pypy/translator/llvm/database.py pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py pypy/release/0.7.x/pypy/translator/llvm/genllvm.py pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c pypy/release/0.7.x/pypy/translator/llvm/module/support.py Log: Start refactoring out our gen ll from c code... and attempt to make the c code not too different from the original. Modified: pypy/release/0.7.x/pypy/translator/llvm/database.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/database.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/database.py Sat Aug 27 13:05:58 2005 @@ -304,6 +304,9 @@ def repr_constructor(self, type_): return self.obj2node[type_].constructor_ref + def repr_name(self, obj): + return self.obj2node[obj].ref + # __________________________________________________________ # Primitive stuff Modified: pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py Sat Aug 27 13:05:58 2005 @@ -9,7 +9,7 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = self.make_ref("%pypy_", value._callable.__name__) + self.ref = self.make_ref("%", value._callable.__name__) def getdecl(self): T = self.value._TYPE Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Sat Aug 27 13:05:58 2005 @@ -29,33 +29,39 @@ function_count = {} llcode_header = ll_functions = None -def get_ll(ccode, extern_dir, functions=[]): - +ll_func_names = [ + "%prepare_and_raise_IOError", + "%prepare_and_raise_ValueError", + "%prepare_and_raise_OverflowError", + "%prepare_and_raise_ZeroDivisionError", + "%RPyString_AsString", + "%RPyString_FromString", + "%RPyString_Size"] + +def get_ll(ccode, function_names): + # goto codespeak and compile our c code request = urllib.urlencode({'ccode':ccode}) llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() - # get rid of the struct that llvm-gcc introduces to struct types - llcode = llcode.replace("%struct.", "%") - - #find function names, declare them internal with fastcc calling convertion + # strip lines ll_lines = [] - funcnames = { - "%RPyString_Size" : True, - "%RPyString_AsString" : True, - "%RPyString_FromString" : True, - "%ll_frexp_result__Float_Signed" : True, - "%ll_modf_result__Float_Float" : True, - "%prepare_and_raise_ZeroDivisionError" : True, - "%prepare_and_raise_OverflowError" : True, - "%prepare_and_raise_ValueError" : True, - "%prepare_and_raise_IOError" : True, - } + function_names = list(function_names) + ll_func_names + funcnames = dict([(k, True) for k in function_names]) + + # strip declares tjat in ll_func_names for line in llcode.split('\n'): + + # get rid of any of the structs that llvm-gcc introduces to struct types + line = line.replace("%struct.", "%") + + # strip comments comment = line.find(';') if comment >= 0: line = line[:comment] line = line.rstrip() + + # find function names, declare them internal with fastcc calling convertion if line[-1:] == '{': returntype, s = line.split(' ', 1) funcname , s = s.split('(', 1) @@ -64,7 +70,7 @@ line = '%s %s %s' % ("", DEFAULT_CCONV, line,) ll_lines.append(line) - #patch calls to function that we just declared fastcc + # patch calls to function that we just declared fastcc ll_lines2, calltag, declaretag = [], 'call ', 'declare ' for line in ll_lines: i = line.find(calltag) @@ -86,31 +92,7 @@ llcode = '\n'.join(ll_lines2) global llcode_header, ll_functions - llcode_header, ll_functions = llcode.split('implementation') # XXX testing - - #XXX temp disabled - # - ## create file - #llfilename = extern_dir.join("externs").new(ext='.ll') - #f = open(str(llfilename), 'w') - #f.write(llcode) - #f.close() - # - # create bytecode - #os.chdir(str(extern_dir)) - #cmdexec('llvm-as externs.ll') - #bcfilename = extern_dir.join("externs").new(ext='.bc') - #if functions: - # for func in functions: - # # extract - # cmdexec('llvm-extract -func %s -o %s.bc externs.bc' % (func, func)) - # - # # link all the ll files - # functions_bcs = ' '.join(['%s.bc' % func for func in functions]) - # cmdexec('llvm-link -o externs_linked.bc ' + functions_bcs) - # bcfilename = extern_dir.join("externs_linked").new(ext='.bc') - # - #return bcfilename + llcode_header, ll_functions = llcode.split('implementation') class GenLLVM(object): @@ -160,44 +142,33 @@ return decls def generate_llfile(self, extern_decls): - - #XXX outcommented because we are not puting files here - #extern_dir = udir.join("externs") - #if extern_dir.check(dir=1): - # return - #extern_dir.mkdir() - extern_dir = None - - genllcode = "" + ccode = [] + function_names = [] def predeclarefn(c_name, llname): + function_names.append(llname) assert llname[0] == "%" + llname = llname[1:] assert '\n' not in llname - return '#define\t%s\t%s' % (c_name, llname[1:]) - + ccode.append('#define\t%s\t%s\n' % (c_name, llname)) + for c_name, obj in extern_decls: if isinstance(obj, lltype.LowLevelType): pass elif isinstance(obj, types.FunctionType): funcptr = getfunctionptr(self.translator, obj) c = inputconst(lltype.typeOf(funcptr), funcptr) - llname = self.db.repr_arg(c) - genllcode += predeclarefn(c_name, llname) + "\n" - #elif isinstance(lltype.typeOf(obj), lltype.Ptr): - # if isinstance(obj.TO, lltype.FuncType): - # llname = self.db.repr_constant(obj)[1] - #XXXXXXXXXXX genllcode += predeclarefn(c_name, llname) + "\n" + predeclarefn(c_name, self.db.repr_arg(c)) + elif isinstance(lltype.typeOf(obj), lltype.Ptr): + if isinstance(lltype.typeOf(obj._obj), lltype.FuncType): + predeclarefn(c_name, self.db.repr_name(obj._obj)) + # append local file j = os.path.join p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") + ccode.append(open(p).read()) - math_fns = 'acos asin atan ceil cos cosh exp fabs floor log log10 atan2 fmod ' - math_fns += 'sin sinh sqrt tan tanh frexp modf pow hypot ldexp is_error' - fns = [('ll_math_%s' % f) for f in math_fns.split()] - fns += "ll_time_time ll_time_clock ll_time_sleep ll_floattime".split() - fns += "ll_strtod_parts_to_float ll_strtod_formatd".split() - - get_ll(open(p).read(), extern_dir, fns) + get_ll("".join(ccode), function_names) def gen_llvm_source(self, func=None): if self.debug: print 'gen_llvm_source begin) ' + time.ctime() @@ -389,7 +360,7 @@ exe_name=exe_name) else: postfix = '' - basename = filename.purebasename+'_wrapper'+postfix+'.pyx' + basename = filename.purebasename + '_wrapper' + postfix + '.pyx' pyxfile = filename.new(basename = basename) write_pyx_wrapper(self.entrynode, pyxfile) return build_llvm_module.make_module_from_llvm(filename, @@ -400,23 +371,12 @@ codewriter.append("declare int %printf(sbyte*, ...)") def genllvm(translator, log_source=False, **kwds): - if not llvm_is_on_path(): - # XXX not good to call py.test.skip here - py.test.skip("llvm not found") - gen = GenLLVM(translator) filename = gen.gen_llvm_source() if log_source: log.genllvm(open(filename).read()) return gen.create_module(filename, **kwds) -def llvm_is_on_path(): - try: - py.path.local.sysfind("llvm-as") - except py.error.ENOENT: - return False - return True - def compile_module(function, annotation, view=False, **kwds): t = Translator(function) a = t.annotate(annotation) Modified: pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c Sat Aug 27 13:05:58 2005 @@ -1,34 +1,34 @@ -#include -#include -#include -#include - -#define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW - -// c forward declarations -double frexp(double, int*); +// Forward declare hacks struct RPyFREXP_RESULT; struct RPyMODF_RESULT; struct RPyString; struct RPySTAT_RESULT; +struct RPyListOfString; -struct RPyFREXP_RESULT *pypy_ll_frexp_result__Float_Signed(double, int); -struct RPyMODF_RESULT *pypy_ll_modf_result__Float_Float(double, double); -struct RPySTAT_RESULT *pypy_ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(int, int, int, int, int, - int, int, int, int, int); +// We hand craft these in module/support.ll +void prepare_and_raise_OverflowError(char *); +void prepare_and_raise_ValueError(char *); +void prepare_and_raise_IOError(char *); char *RPyString_AsString(struct RPyString*); int RPyString_Size(struct RPyString*); struct RPyString *RPyString_FromString(char *); -void prepare_and_raise_OverflowError(char *); -void prepare_and_raise_ValueError(char *); -void prepare_and_raise_IOError(char *); -void pypy_ll_raise_OSError__Signed(int error); +// Generated by rpython - argggh have to feed in prototypes +struct RPyFREXP_RESULT *ll_frexp_result(double, int); +struct RPyMODF_RESULT *ll_modf_result(double, double); +struct RPySTAT_RESULT *ll_stat_result(int, int, int, int, int, int, int, int, int, int); +void RPYTHON_RAISE_OSERROR(int error); +int pypy_entry_point(struct RPyListOfString*); -#define RPYTHON_RAISE_OSERROR(error) pypy_ll_raise_OSError__Signed(error) +#include +#include +#include +#include + +#define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW -int pypy_ll_math_is_error(double x) { +int ll_math_is_error(double x) { if (errno == ERANGE) { if (!x) return 0; @@ -43,12 +43,12 @@ #define LL_MATH_CHECK_ERROR(x, errret) do { \ LL_MATH_SET_ERANGE_IF_MATH_ERROR(x); \ - if (errno && pypy_ll_math_is_error(x)) \ + if (errno && ll_math_is_error(x)) \ return errret; \ } while(0) -double pypy_ll_math_pow(double x, double y) { +double ll_math_pow(double x, double y) { double r; LL_MATH_ERROR_RESET; r = pow(x, y); @@ -56,7 +56,7 @@ return r; } -double pypy_ll_math_atan2(double x, double y) { +double ll_math_atan2(double x, double y) { double r; LL_MATH_ERROR_RESET; r = atan2(x, y); @@ -64,7 +64,7 @@ return r; } -double pypy_ll_math_fmod(double x, double y) { +double ll_math_fmod(double x, double y) { double r; LL_MATH_ERROR_RESET; r = fmod(x, y); @@ -72,7 +72,7 @@ return r; } -double pypy_ll_math_ldexp(double x, long y) { +double ll_math_ldexp(double x, long y) { double r; LL_MATH_ERROR_RESET; r = ldexp(x, (int) y); @@ -80,7 +80,7 @@ return r; } -double pypy_ll_math_hypot(double x, double y) { +double ll_math_hypot(double x, double y) { double r; LL_MATH_ERROR_RESET; r = hypot(x, y); @@ -88,17 +88,17 @@ return r; } -struct RPyMODF_RESULT* pypy_ll_math_modf(double x) { +struct RPyMODF_RESULT* ll_math_modf(double x) { double intpart, fracpart; LL_MATH_ERROR_RESET; fracpart = modf(x, &intpart); LL_MATH_CHECK_ERROR(fracpart, NULL); - return pypy_ll_modf_result__Float_Float(fracpart, intpart); + return ll_modf_result(fracpart, intpart); } /* simple math function */ -double pypy_ll_math_acos(double x) { +double ll_math_acos(double x) { double r; LL_MATH_ERROR_RESET; r = acos(x); @@ -106,7 +106,7 @@ return r; } -double pypy_ll_math_asin(double x) { +double ll_math_asin(double x) { double r; LL_MATH_ERROR_RESET; r = asin(x); @@ -114,7 +114,7 @@ return r; } -double pypy_ll_math_atan(double x) { +double ll_math_atan(double x) { double r; LL_MATH_ERROR_RESET; r = atan(x); @@ -122,7 +122,7 @@ return r; } -double pypy_ll_math_ceil(double x) { +double ll_math_ceil(double x) { double r; LL_MATH_ERROR_RESET; r = ceil(x); @@ -130,7 +130,7 @@ return r; } -double pypy_ll_math_cos(double x) { +double ll_math_cos(double x) { double r; LL_MATH_ERROR_RESET; r = cos(x); @@ -138,7 +138,7 @@ return r; } -double pypy_ll_math_cosh(double x) { +double ll_math_cosh(double x) { double r; LL_MATH_ERROR_RESET; r = cosh(x); @@ -146,7 +146,7 @@ return r; } -double pypy_ll_math_exp(double x) { +double ll_math_exp(double x) { double r; LL_MATH_ERROR_RESET; r = exp(x); @@ -154,7 +154,7 @@ return r; } -double pypy_ll_math_fabs(double x) { +double ll_math_fabs(double x) { double r; LL_MATH_ERROR_RESET; r = fabs(x); @@ -162,7 +162,7 @@ return r; } -double pypy_ll_math_floor(double x) { +double ll_math_floor(double x) { double r; LL_MATH_ERROR_RESET; r = floor(x); @@ -170,7 +170,7 @@ return r; } -double pypy_ll_math_log(double x) { +double ll_math_log(double x) { double r; LL_MATH_ERROR_RESET; r = log(x); @@ -178,7 +178,7 @@ return r; } -double pypy_ll_math_log10(double x) { +double ll_math_log10(double x) { double r; LL_MATH_ERROR_RESET; r = log10(x); @@ -186,7 +186,7 @@ return r; } -double pypy_ll_math_sin(double x) { +double ll_math_sin(double x) { double r; LL_MATH_ERROR_RESET; r = sin(x); @@ -194,7 +194,7 @@ return r; } -double pypy_ll_math_sinh(double x) { +double ll_math_sinh(double x) { double r; LL_MATH_ERROR_RESET; r = sinh(x); @@ -202,7 +202,7 @@ return r; } -double pypy_ll_math_sqrt(double x) { +double ll_math_sqrt(double x) { double r; LL_MATH_ERROR_RESET; r = sqrt(x); @@ -210,7 +210,7 @@ return r; } -double pypy_ll_math_tan(double x) { +double ll_math_tan(double x) { double r; LL_MATH_ERROR_RESET; r = tan(x); @@ -218,7 +218,7 @@ return r; } -double pypy_ll_math_tanh(double x) { +double ll_math_tanh(double x) { double r; LL_MATH_ERROR_RESET; r = tanh(x); @@ -226,13 +226,13 @@ return r; } -struct RPyFREXP_RESULT* pypy_ll_math_frexp(double x) { +struct RPyFREXP_RESULT* ll_math_frexp(double x) { int expo; double m; LL_MATH_ERROR_RESET; m= frexp(x, &expo); LL_MATH_CHECK_ERROR(m, NULL); - return pypy_ll_frexp_result__Float_Signed(m, expo); + return ll_frexp_result(m, expo); } /************************************************************/ @@ -251,7 +251,7 @@ XXX Win64 does not yet, but might when the platform matures. */ #include -double pypy_ll_time_clock(void) +double ll_time_clock(void) { static LARGE_INTEGER ctrStart; static double divisor = 0.0; @@ -283,14 +283,14 @@ #endif #endif -double pypy_ll_time_clock(void) +double ll_time_clock(void) { return ((double)clock()) / CLOCKS_PER_SEC; } #endif /* MS_WINDOWS */ -void pypy_ll_time_sleep(double secs) +void ll_time_sleep(double secs) { #if defined(MS_WINDOWS) double millisecs = secs * 1000.0; @@ -343,7 +343,7 @@ #endif /* MS_WINDOWS */ #endif /* HAVE_FTIME */ -double pypy_ll_floattime(void) +double ll_floattime(void) { /* There are three ways to get the time: (1) gettimeofday() -- resolution in microseconds @@ -378,13 +378,13 @@ } } -double pypy_ll_time_time(void) /* xxx had support for better resolutions */ +double ll_time_time(void) /* xxx had support for better resolutions */ { - return pypy_ll_floattime(); + return ll_floattime(); } -double pypy_ll_strtod_parts_to_float(struct RPyString *sign, +double ll_strtod_parts_to_float(struct RPyString *sign, struct RPyString *beforept, struct RPyString *afterpt, struct RPyString *exponent) @@ -445,7 +445,7 @@ } -struct RPyString *pypy_ll_strtod_formatd(struct RPyString *fmt, double x) { +struct RPyString *ll_strtod_formatd(struct RPyString *fmt, double x) { char buffer[120]; /* this should be enough, from PyString_Format code */ int buflen = 120; int res; @@ -512,9 +512,9 @@ /* The functions below are mapped to functions from pypy.rpython.module.* by the pypy.translator.c.extfunc.EXTERNALS dictionary. They should correspond to the functions with the suggested_primitive - flag set, and NOT necessarily directly to the pypy_ll_os_*() functions. - See for example pypy_ll_read_into(), which is called by pypy_ll_os_read(). - The latter would be messy to write here, but pypy_ll_read_into() is quite easy. + flag set, and NOT necessarily directly to the ll_os_*() functions. + See for example ll_read_into(), which is called by ll_os_read(). + The latter would be messy to write here, but ll_read_into() is quite easy. */ @@ -531,7 +531,7 @@ #endif -int pypy_ll_os_open(struct RPyString *filename, int flag, int mode) +int ll_os_open(struct RPyString *filename, int flag, int mode) { /* XXX unicode_file_names */ char buf[PATH_MAX]; @@ -550,7 +550,7 @@ } } -long pypy_ll_read_into(int fd, struct RPyString *buffer) +long ll_read_into(int fd, struct RPyString *buffer) { long n = read(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) @@ -558,7 +558,7 @@ return n; } -long pypy_ll_os_write(int fd, struct RPyString *buffer) +long ll_os_write(int fd, struct RPyString *buffer) { long n = write(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) @@ -566,13 +566,13 @@ return n; } -void pypy_ll_os_close(int fd) +void ll_os_close(int fd) { if (close(fd) < 0) RPYTHON_RAISE_OSERROR(errno); } -int pypy_ll_os_dup(int fd) +int ll_os_dup(int fd) { fd = dup(fd); if (fd < 0) @@ -580,7 +580,7 @@ return fd; } -struct RPyString *pypy_ll_os_getcwd(void) +struct RPyString *ll_os_getcwd(void) { char buf[PATH_MAX]; char *res; @@ -606,12 +606,11 @@ res9 = (long)st.st_ctime; /*XXX ignoring quite a lot of things for time here */ /*XXX ignoring BLOCK info here*/ - return pypy_ll_stat_result__Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed_Signed(res0, res1, res2, res3, res4, - res5, res6, res7, res8, res9); + return ll_stat_result(res0, res1, res2, res3, res4, res5, res6, res7, res8, res9); } -struct RPySTAT_RESULT* pypy_ll_os_stat(struct RPyString * fname) { +struct RPySTAT_RESULT* ll_os_stat(struct RPyString * fname) { STRUCT_STAT st; int error = STAT(RPyString_AsString(fname), &st); if (error != 0) { @@ -621,7 +620,7 @@ return _stat_construct_result_helper(st); } -struct RPySTAT_RESULT* pypy_ll_os_fstat(long fd) { +struct RPySTAT_RESULT* ll_os_fstat(long fd) { STRUCT_STAT st; int error = FSTAT(fd, &st); if (error != 0) { @@ -631,7 +630,7 @@ return _stat_construct_result_helper(st); } -long pypy_ll_os_lseek(long fd, long pos, long how) { +long ll_os_lseek(long fd, long pos, long how) { #if defined(MS_WIN64) || defined(MS_WINDOWS) PY_LONG_LONG res; #else @@ -655,12 +654,12 @@ return res; } -long pypy_ll_os_isatty(long fd) { +long ll_os_isatty(long fd) { return (int)isatty((int)fd); } #ifdef HAVE_FTRUNCATE -void pypy_ll_os_ftruncate(long fd, long length) { /*XXX add longfile support */ +void ll_os_ftruncate(long fd, long length) { /*XXX add longfile support */ int res; res = ftruncate((int)fd, (off_t)length); if (res < 0) { @@ -669,38 +668,38 @@ } #endif -struct RPyString *pypy_ll_os_strerror(int errnum) { +struct RPyString *ll_os_strerror(int errnum) { char *res; res = strerror(errnum); return RPyString_FromString(res); } -long pypy_ll_os_system(struct RPyString * fname) { +long ll_os_system(struct RPyString * fname) { return system(RPyString_AsString(fname)); } -void pypy_ll_os_unlink(struct RPyString * fname) { +void ll_os_unlink(struct RPyString * fname) { int error = unlink(RPyString_AsString(fname)); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } } -void pypy_ll_os_chdir(struct RPyString * path) { +void ll_os_chdir(struct RPyString * path) { int error = chdir(RPyString_AsString(path)); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } } -void pypy_ll_os_mkdir(struct RPyString * path, int mode) { +void ll_os_mkdir(struct RPyString * path, int mode) { int error = mkdir(RPyString_AsString(path), mode); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } } -void pypy_ll_os_rmdir(struct RPyString * path) { +void ll_os_rmdir(struct RPyString * path) { int error = rmdir(RPyString_AsString(path)); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/support.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/support.py Sat Aug 27 13:05:58 2005 @@ -43,7 +43,6 @@ %sizeptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 0 %size = load int* %sizeptr ret int %size - } """) @@ -266,44 +265,6 @@ } """ % locals()) -extfunctions["%main"] = [(), """ -int %main(int %argc, sbyte** %argv) { -entry: - %pypy_argv = call fastcc %RPyListOfString* %pypy_ll_newlist__listPtrConst_Signed(int 0) - br label %no_exit - -no_exit: - %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] - %i.0.0 = cast uint %indvar to int - %tmp.8 = getelementptr sbyte** %argv, uint %indvar - %tmp.9 = load sbyte** %tmp.8 - - %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 - %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) - %cond = seteq int %res, 0 - br bool %cond, label %debugging, label %not_debugging - -debugging: - store bool true, bool* %__print_debug_info - br label %next_arg - -not_debugging: - %rpy = call fastcc %RPyString* %RPyString_FromString(sbyte* %tmp.9) - call fastcc void %pypy_ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) - br label %next_arg - -next_arg: - %inc = add int %i.0.0, 1 - %tmp.2 = setlt int %inc, %argc - %indvar.next = add uint %indvar, 1 - br bool %tmp.2, label %no_exit, label %loopexit - -loopexit: - %ret = call fastcc int %pypy_entry_point(%structtype.list* %pypy_argv) - ret int %ret -} -"""] - extfunctions["%main_noargs"] = [(), """ int %main(int %argc, sbyte** %argv) { entry: From ac at codespeak.net Sat Aug 27 13:08:25 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 27 Aug 2005 13:08:25 +0200 (CEST) Subject: [pypy-svn] r16740 - pypy/release/0.7.x/pypy/interpreter Message-ID: <20050827110825.CCC3C27B56@code1.codespeak.net> Author: ac Date: Sat Aug 27 13:08:25 2005 New Revision: 16740 Modified: pypy/release/0.7.x/pypy/interpreter/pyopcode.py Log: Accept non-dict objects as globals/locals to exec as long as they have __getitem__. Modified: pypy/release/0.7.x/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyopcode.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyopcode.py Sat Aug 27 13:08:25 2005 @@ -874,12 +874,14 @@ locals = globals if not isinstance(globals, dict): - if hasattr(globals, '__getitem__'): + if not hasattr(globals, '__getitem__'): raise TypeError("exec: arg 2 must be a dictionary or None") - if '__builtins__' not in globals: + try: + globals['__builtins__'] + except KeyError: globals['__builtins__'] = builtin if not isinstance(locals, dict): - if hasattr(locals, '__getitem__'): + if not hasattr(locals, '__getitem__'): raise TypeError("exec: arg 3 must be a dictionary or None") if not isinstance(prog, codetype): From ale at codespeak.net Sat Aug 27 13:12:06 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Sat, 27 Aug 2005 13:12:06 +0200 (CEST) Subject: [pypy-svn] r16742 - in pypy/release/0.7.x/pypy/tool/pytest: . test test/data Message-ID: <20050827111206.38CBF27B46@code1.codespeak.net> Author: ale Date: Sat Aug 27 13:12:04 2005 New Revision: 16742 Added: pypy/release/0.7.x/pypy/tool/pytest/test/data/ pypy/release/0.7.x/pypy/tool/pytest/test/data/test___all__.txt pypy/release/0.7.x/pypy/tool/pytest/test/data/test_compile.txt pypy/release/0.7.x/pypy/tool/pytest/test/data/test_descr.txt pypy/release/0.7.x/pypy/tool/pytest/test/data/test_generators.txt pypy/release/0.7.x/pypy/tool/pytest/test/data/test_global.txt pypy/release/0.7.x/pypy/tool/pytest/test/data/test_sys.txt pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py Modified: pypy/release/0.7.x/pypy/tool/pytest/result.py Log: New method for counting the ratio of passing test. It tries to count the nimber of passing testcases in a not complete passing testmodule and returns a number between 0 and 1. Added tests as well Modified: pypy/release/0.7.x/pypy/tool/pytest/result.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/result.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/result.py Sat Aug 27 13:12:04 2005 @@ -1,5 +1,6 @@ import sys import py +import re class Result(object): def __init__(self, init=True): @@ -67,10 +68,40 @@ outer.attach(m) return outer - def isok(self): + def grep_nr(self,text,section='stdout'): + stdout = self._blocks[section] + find = re.search('%s(?P\d+)'%text,stdout) + if find: + return float(find.group('nr')) + return 0. + + def ratio_of_passed(self): + if self.isok(): + return 1. + elif self.istimeout(): + return 0. + else: + nr = self.grep_nr('Ran ') + if nr > 0: + return (nr - (self.grep_nr('errors=') + self.grep_nr('failures=')))/nr + else: + passed = self.grep_nr('TestFailed: ',section='stderr') + run = self.grep_nr('TestFailed: \d+/',section='stderr') + if run > 0: + return passed/run + else: + run = self.grep_nr('TestFailed: \d+ of ',section='stderr') + if run >0 : + return (run-passed)/run + else: + return 0 + + def isok(self): return self['outcome'].lower() == 'ok' - def iserror(self): + + def iserror(self): return self['outcome'].lower()[:3] == 'err' + def istimeout(self): return self['outcome'].lower() == 't/o' Added: pypy/release/0.7.x/pypy/tool/pytest/test/data/test___all__.txt ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/pytest/test/data/test___all__.txt Sat Aug 27 13:12:04 2005 @@ -0,0 +1,94 @@ +Content-Type: multipart/mixed; boundary="===============0790678169==" +MIME-Version: 1.0 +execution-time: 1445.14346004 +exit status: 1 +fspath: /Users/anderslehmann/pypy/lib-python/2.4.1/test/test___all__.py +options: ['core', '_sre'] +outcome: T/O +platform: darwin +pypy-revision: 16114 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Wed Aug 17 23:51:59 2005 +testreport-version: 1.1 +timeout: 1369.0 +userhost: anderslehmann at anders-lehmanns-15-powerbook-g4.local +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============0790678169== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +test_all (__main__.AllTest) ... ERROR + +====================================================================== +ERROR: test_all (__main__.AllTest) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test___all__.py", line 163, in test_all + self.check_all("tty") + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test___all__.py", line 26, in check_all + "%s has no __all__ attribute" % modname) + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_support.py", line 208, in verify + raise TestFailed(reason) +TestFailed: tty has no __all__ attribute + +---------------------------------------------------------------------- + +--===============0790678169== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +faking +Loading grammar /Users/anderslehmann/pypy/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0x12068> +fake-wrapping interp file ', mode 'w' at 0x120b0> +fake-wrapping interp file ', mode 'r' at 0x12020> +faking +faking +faking +faking +==========================timedout========================== +Traceback (application-level): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test___all__.py", line 192 in + test_main() + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test___all__.py", line 189 in test_main + test_support.run_unittest(AllTest) + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_support.py", line 290 in run_unittest + run_suite(suite, testclass) + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_support.py", line 262 in run_suite + result = runner.run(suite) +Traceback (application-level): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/atexit.py", line 29 in _run_exitfuncs + print >> sys.stderr, "Error in atexit._run_exitfuncs:" +KeyboardInterrupt +Traceback (most recent call last): + File "/Users/anderslehmann/pypy/pypy/tool/alarm.py", line 43, in ? + execfile(_main_with_alarm(finished)) + File "/Users/anderslehmann/pypy/pypy/bin/py.py", line 206, in ? + sys.exit(main_(sys.argv)) + File "/Users/anderslehmann/pypy/pypy/bin/py.py", line 115, in main_ + if not main.run_toplevel(space, doit, verbose=Options.verbose): + File "/Users/anderslehmann/pypy/pypy/interpreter/main.py", line 150, in run_toplevel + operationerr.print_application_traceback(space) + File "/Users/anderslehmann/pypy/pypy/interpreter/error.py", line 83, in print_application_traceback + self.print_app_tb_only(file) + File "/Users/anderslehmann/pypy/pypy/interpreter/error.py", line 104, in print_app_tb_only + l = linecache.getline(fname, lineno) + File "/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/linecache.py", line 14, in getline + lines = getlines(filename) + File "/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/linecache.py", line 40, in getlines + return updatecache(filename) + File "/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/linecache.py", line 101, in updatecache + lines = fp.readlines() +KeyboardInterrupt + +--===============0790678169==-- \ No newline at end of file Added: pypy/release/0.7.x/pypy/tool/pytest/test/data/test_compile.txt ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/pytest/test/data/test_compile.txt Sat Aug 27 13:12:04 2005 @@ -0,0 +1,111 @@ +Content-Type: multipart/mixed; boundary="===============2137793924==" +MIME-Version: 1.0 +execution-time: 34.8464071751 +exit status: 1 +fspath: /Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py +options: ['core', '_sre'] +outcome: ERR +platform: darwin +pypy-revision: 16114 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Thu Aug 18 03:08:18 2005 +testreport-version: 1.1 +timeout: 1521.0 +userhost: anderslehmann at anders-lehmanns-15-powerbook-g4.local +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============2137793924== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +test_argument_handling (__main__.TestSpecifics) ... FAIL +test_argument_order (__main__.TestSpecifics) ... FAIL +test_complex_args (__main__.TestSpecifics) ... ok +test_debug_assignment (__main__.TestSpecifics) ... FAIL +test_duplicate_global_local (__main__.TestSpecifics) ... ok +test_exec_with_general_mapping_for_locals (__main__.TestSpecifics) ... ok +test_float_literals (__main__.TestSpecifics) ... ok +test_for_distinct_code_objects (__main__.TestSpecifics) ... ok +test_import (__main__.TestSpecifics) ... FAIL +test_indentation (__main__.TestSpecifics) ... ok +test_literals_with_leading_zeroes (__main__.TestSpecifics) ... ok +test_none_assignment (__main__.TestSpecifics) ... FAIL +test_sequence_unpacking_error (__main__.TestSpecifics) ... ok +test_syntax_error (__main__.TestSpecifics) ... ok +test_unary_minus (__main__.TestSpecifics) ... ok + +====================================================================== +FAIL: test_argument_handling (__main__.TestSpecifics) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py", line 18, in test_argument_handling + self.assertRaises(SyntaxError, eval, 'lambda a,a:0') +AssertionError: SyntaxError not raised + +====================================================================== +FAIL: test_argument_order (__main__.TestSpecifics) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py", line 127, in test_argument_order + self.fail("non-default args after default") +AssertionError: non-default args after default + +====================================================================== +FAIL: test_debug_assignment (__main__.TestSpecifics) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py", line 10, in test_debug_assignment + self.assertRaises(SyntaxError, compile, '__debug__ = 1', '?', 'single') +AssertionError: SyntaxError not raised + +====================================================================== +FAIL: test_import (__main__.TestSpecifics) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py", line 253, in test_import + self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'exec') +AssertionError: SyntaxError not raised + +====================================================================== +FAIL: test_none_assignment (__main__.TestSpecifics) +---------------------------------------------------------------------- +Traceback (most recent call last): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py", line 211, in test_none_assignment + self.assertRaises(SyntaxError, compile, stmt, 'tmp', 'single') +AssertionError: SyntaxError not raised + +---------------------------------------------------------------------- +Ran 15 tests in 14.363s + +FAILED (failures=5) + +--===============2137793924== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +faking +Loading grammar /Users/anderslehmann/pypy/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0x12068> +fake-wrapping interp file ', mode 'w' at 0x120b0> +fake-wrapping interp file ', mode 'r' at 0x12020> +Traceback (application-level): + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py", line 268 in + test_main() + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_compile.py", line 265 in test_main + test_support.run_unittest(TestSpecifics) + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_support.py", line 290 in run_unittest + run_suite(suite, testclass) + File "/Users/anderslehmann/pypy/lib-python/2.4.1/test/test_support.py", line 274 in run_suite + raise TestFailed(msg) +TestFailed: errors occurred in __main__.TestSpecifics + +--===============2137793924==-- \ No newline at end of file Added: pypy/release/0.7.x/pypy/tool/pytest/test/data/test_descr.txt ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/pytest/test/data/test_descr.txt Sat Aug 27 13:12:04 2005 @@ -0,0 +1,233 @@ +Content-Type: multipart/mixed; boundary="===============1265023865==" +MIME-Version: 1.0 +execution-time: 4098.8407588 +exit status: 1 +fspath: /Users/anderslehmann/pypy/lib-python/modified-2.4.1/test/test_descr.py +options: ['oldstyle', 'core'] +outcome: ERR +platform: darwin +pypy-revision: 16388 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Wed Aug 24 16:54:12 2005 +testreport-version: 1.1 +timeout: 10000.0 +userhost: anderslehmann at anders-lehmanns-15-powerbook-g4.local +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============1265023865== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +**************************************** +--> weakref_segfault FAILURE(0/92) _weakref +**************************************** +--> do_this_first OK(1/92) +**************************************** +--> class_docstrings OK(2/92) +**************************************** +--> lists FAILURE(2/92) type object 'list' has no attribute '__getslice__' +**************************************** +--> dicts FAILURE(2/92) type object 'dict' has no attribute '__cmp__' +**************************************** +--> dict_constructor OK(3/92) +**************************************** +--> test_dir OK(4/92) +**************************************** +--> ints OK(5/92) +**************************************** +--> longs OK(6/92) +**************************************** +--> floats OK(7/92) +**************************************** +--> complexes OK(8/92) +**************************************** +--> spamlists FAILURE(8/92) xxsubtype +**************************************** +--> spamdicts FAILURE(8/92) xxsubtype +**************************************** +--> pydicts OK(9/92) +**************************************** +--> pylists OK(10/92) +**************************************** +--> metaclass OK(11/92) +**************************************** +--> pymods OK(12/92) +**************************************** +--> multi OK(13/92) +**************************************** +--> mro_disagreement FAILURE(13/92) Message 'cycle among base classes: A < B < A', expected 'Cannot create a consistent method resolution\norder (MRO) for bases ' +**************************************** +--> diamond OK(14/92) +**************************************** +--> ex5 OK(15/92) +**************************************** +--> monotonicity OK(16/92) +**************************************** +--> consistency_with_epg OK(17/92) +**************************************** +--> objects OK(18/92) +**************************************** +--> slots FAILURE(18/92) ['foo bar'] slots not caught +**************************************** +--> slotspecials FAILURE(18/92) test failed +**************************************** +--> dynamics OK(19/92) +**************************************** +--> errors FAILURE(19/92) inheritance from CFunction should be illegal +**************************************** +--> classmethods OK(20/92) +**************************************** +--> classmethods_in_c FAILURE(20/92) xxsubtype +**************************************** +--> staticmethods OK(21/92) +**************************************** +--> staticmethods_in_c FAILURE(21/92) xxsubtype +**************************************** +--> classic OK(22/92) +**************************************** +--> compattr OK(23/92) +**************************************** +--> newslot OK(24/92) +**************************************** +--> altmro OK(25/92) +**************************************** +--> overloading OK(26/92) +**************************************** +--> methods FAILURE(26/92) test failed +**************************************** +--> specials FAILURE(26/92) shouldn't allow .__cmp__(u'123', '123') +**************************************** +--> weakrefs FAILURE(26/92) 'module' object has no attribute 'ref' +**************************************** +--> properties FAILURE(26/92) expected TypeError from trying to set readonly '__doc__' attr on a property +**************************************** +--> supers OK(27/92) +**************************************** +--> inherits FAILURE(27/92) test failed +**************************************** +--> keywords FAILURE(27/92) descr__new__() got an unexpected keyword argument 'string' +**************************************** +--> restricted OK(28/92) +**************************************** +--> str_subclass_as_dict_key OK(29/92) +**************************************** +--> classic_comparisons OK(30/92) +**************************************** +--> rich_comparisons OK(31/92) +**************************************** +--> coercions OK(32/92) +**************************************** +--> descrdoc FAILURE(32/92) 'The most base type' == 'True if the file is closed' +**************************************** +--> setclass OK(33/92) +**************************************** +--> setdict OK(34/92) +**************************************** +--> pickles OK(35/92) +**************************************** +--> copies OK(36/92) +**************************************** +--> binopoverride OK(37/92) +**************************************** +--> subclasspropagation OK(38/92) +**************************************** +--> buffer_inherit OK(39/92) +**************************************** +--> str_of_str_subclass OK(40/92) +**************************************** +--> kwdargs OK(41/92) +**************************************** +--> delhook OK(42/92) +**************************************** +--> hashinherit OK(43/92) +**************************************** +--> strops OK(44/92) +**************************************** +--> deepcopyrecursive OK(45/92) +**************************************** +--> modules OK(46/92) +**************************************** +--> dictproxyiterkeys FAILURE(46/92) ['__dict__', '__module__', 'meth'] == ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'] +**************************************** +--> dictproxyitervalues FAILURE(46/92) 3 == 5 +**************************************** +--> dictproxyiteritems FAILURE(46/92) ['__dict__', '__module__', 'meth'] == ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'] +**************************************** +--> pickleslots OK(47/92) +**************************************** +--> funnynew OK(48/92) +**************************************** +--> imulbug OK(49/92) +**************************************** +--> docdescriptor OK(50/92) +**************************************** +--> string_exceptions FAILURE(50/92) string subclass allowed as exception +**************************************** +--> copy_setstate OK(51/92) +**************************************** +--> slices OK(52/92) +**************************************** +--> subtype_resurrection OK(53/92) +**************************************** +--> slottrash OK(54/92) +**************************************** +--> slotmultipleinheritance FAILURE(54/92) type object 'C' has no attribute '__basicsize__' +**************************************** +--> testrmul OK(55/92) +**************************************** +--> testipow OK(56/92) +**************************************** +--> test_mutable_bases FAILURE(56/92) readonly attribute +**************************************** +--> test_mutable_bases_with_failing_mro FAILURE(56/92) readonly attribute +**************************************** +--> test_mutable_bases_catch_mro_conflict OK(57/92) +**************************************** +--> mutable_names OK(58/92) +**************************************** +--> subclass_right_op OK(59/92) +**************************************** +--> dict_type_with_metaclass OK(60/92) +**************************************** +--> meth_class_get FAILURE(60/92) shouldn't have allowed descr.__get__(None, None) +**************************************** +--> isinst_isclass OK(61/92) +**************************************** +--> proxysuper OK(62/92) +**************************************** +--> carloverre OK(63/92) +**************************************** +--> filefault OK(64/92) +**************************************** +--> vicious_descriptor_nonsense OK(65/92) +**************************************** +--> test_init FAILURE(65/92) did not test __init__() for None return + +--===============1265023865== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +faking +Loading grammar /Users/anderslehmann/pypy/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0x12068> +fake-wrapping interp file ', mode 'w' at 0x120b0> +fake-wrapping interp file ', mode 'r' at 0x12020> +faking +faking +Traceback (application-level): + File "/Users/anderslehmann/pypy/pypy/tool/pytest/regrverbose.py", line 12 in + indirect_test() + File "/Users/anderslehmann/pypy/lib-python/modified-2.4.1/test/test_descr.py", line 4102 in test_main + raise TestFailed, "%d/%d" % (success, n) +TestFailed: 65/92 + +--===============1265023865==-- \ No newline at end of file Added: pypy/release/0.7.x/pypy/tool/pytest/test/data/test_generators.txt ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/pytest/test/data/test_generators.txt Sat Aug 27 13:12:04 2005 @@ -0,0 +1,317 @@ +Content-Type: multipart/mixed; boundary="===============1565511160==" +MIME-Version: 1.0 +cpu mhz: unknown +cpu model: unknown +execution-time: 671.678878069 +exit status: 1 +fspath: /home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py +options: ['core'] +outcome: ERR +platform: linux2 +pypy-revision: 16123 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Thu Aug 18 02:08:13 2005 +testreport-version: 1.1 +timeout: 3136.0 +userhost: xoraxax at tick +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============1565511160== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + import weakref +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + import weakref + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/weakref.py", line 14, in + from _weakref import ( + ImportError: _weakref +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + wr = weakref.ref(gen) +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + wr = weakref.ref(gen) + NameError: global name 'weakref' is not defined +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + wr() is gen +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + wr() is gen + NameError: global name 'wr' is not defined +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + p = weakref.proxy(gen) +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + p = weakref.proxy(gen) + NameError: global name 'weakref' is not defined +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + wr = weakref.ref(gi) +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + wr = weakref.ref(gi) + NameError: global name 'weakref' is not defined +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + wr() is gi +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + wr() is gi + NameError: global name 'wr' is not defined +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + p = weakref.proxy(gi) +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + p = weakref.proxy(gi) + NameError: global name 'weakref' is not defined +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.weakref +Failed example: + list(p) +Exception raised: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + list(p) + NameError: global name 'p' is not defined +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.pep +Failed example: + k.next() +Expected: + Traceback (most recent call last): + File "", line 1, in ? + File "", line 2, in g + File "", line 2, in f + ZeroDivisionError: integer division or modulo by zero +Got: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 1, in + k.next() + File "", line 2, in g + yield f() # the zero division exception propagates + File "", line 2, in f + return 1//0 + ZeroDivisionError: integer division by zero +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + return 22 + yield 1 +Expected: + Traceback (most recent call last): + .. + SyntaxError: 'return' with argument inside generator (, line 2) +Got nothing +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + yield 1 + return 22 +Expected: + Traceback (most recent call last): + .. + SyntaxError: 'return' with argument inside generator (, line 3) +Got nothing +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + yield 1 + return None +Expected: + Traceback (most recent call last): + .. + SyntaxError: 'return' with argument inside generator (, line 3) +Got nothing +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + try: + yield 1 + finally: + pass +Expected: + Traceback (most recent call last): + .. + SyntaxError: 'yield' not allowed in a 'try' block with a 'finally' clause (, line 3) +Got nothing +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + try: + try: + 1//0 + except ZeroDivisionError: + yield 666 # bad because *outer* try has finally + except: + pass + finally: + pass +Expected: + Traceback (most recent call last): + ... + SyntaxError: 'yield' not allowed in a 'try' block with a 'finally' clause (, line 6) +Got nothing +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + yield +Expected: + Traceback (most recent call last): + SyntaxError: invalid syntax +Got: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 2 + def f(): + ^ + SyntaxError: error +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + if 0: + yield +Expected: + Traceback (most recent call last): + SyntaxError: invalid syntax +Got: + Traceback (most recent call last): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/doctest.py", line 1243, in __run + compileflags, 1) in test.globs + File "", line 3 + def f(): + ^ + SyntaxError: error +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + type(f()) +Expected: + +Got: + +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + type(f()) +Expected: + +Got: + +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + type(f()) +Expected: + +Got: + +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + type(f()) +Expected: + +Got: + +********************************************************************** +File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line ?, in test.test_generators.__test__.syntax +Failed example: + def f(): + if 0: + lambda x: x # shouldn't trigger here + return # or here + def f(i): + return 2*i # or here + if 0: + return 3 # but *this* sucks (line 8) + if 0: + yield 2 # because it's a generator +Expected: + Traceback (most recent call last): + SyntaxError: 'return' with argument inside generator (, line 8) +Got nothing +********************************************************************** +3 items had failures: + 1 of 22 in test.test_generators.__test__.pep + 12 of 29 in test.test_generators.__test__.syntax + 8 of 10 in test.test_generators.__test__.weakref +***Test Failed*** 21 failures. + +--===============1565511160== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +faking +Loading grammar /home/contest/xoraxax/pypy-dist/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0xf7fa3068> +fake-wrapping interp file ', mode 'w' at 0xf7fa30b0> +fake-wrapping interp file ', mode 'r' at 0xf7fa3020> +faking +faking +faking +Traceback (application-level): + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line 1405 in + test_main(1) + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_generators.py", line 1401 in test_main + test_support.run_doctest(test_generators, verbose) + File "/home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_support.py", line 319 in run_doctest + finally: +TestFailed: 21 of 154 doctests failed + +--===============1565511160==-- \ No newline at end of file Added: pypy/release/0.7.x/pypy/tool/pytest/test/data/test_global.txt ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/pytest/test/data/test_global.txt Sat Aug 27 13:12:04 2005 @@ -0,0 +1,94 @@ +Content-Type: multipart/mixed; boundary="===============1988336873==" +MIME-Version: 1.0 +cpu mhz: unknown +cpu model: unknown +execution-time: 12.6530230045 +exit status: 2 +fspath: /home/contest/xoraxax/pypy-dist/lib-python/2.4.1/test/test_global.py +options: ['core'] +outcome: ERROUT +platform: linux2 +pypy-revision: 16123 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Thu Aug 18 02:12:59 2005 +testreport-version: 1.1 +timeout: 3844.0 +userhost: xoraxax at tick +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============1988336873== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +should have raised SyntaxError: +def wrong1(): + a = 1 + b = 2 + global a + global b + +should have raised SyntaxError: +def wrong2(): + print x + global x + +should have raised SyntaxError: +def wrong3(): + print x + x = 2 + global x + +as expected, no SyntaxError + +--===============1988336873== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +faking +Loading grammar /home/contest/xoraxax/pypy-dist/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0xf7fa3068> +fake-wrapping interp file ', mode 'w' at 0xf7fa30b0> +fake-wrapping interp file ', mode 'r' at 0xf7fa3020> +faking + +--===============1988336873== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="reportdiff" + +********************************************************************** +*** mismatch between lines 2-4 of expected output and lines 2-19 of actual output: +- got SyntaxError as expected +- got SyntaxError as expected +- got SyntaxError as expected ++ should have raised SyntaxError: ++ def wrong1(): ++ a = 1 ++ b = 2 ++ global a ++ global b ++ ++ should have raised SyntaxError: ++ def wrong2(): ++ print x ++ global x ++ ++ should have raised SyntaxError: ++ def wrong3(): ++ print x ++ x = 2 ++ global x ++ +********************************************************************** + +--===============1988336873==-- \ No newline at end of file Added: pypy/release/0.7.x/pypy/tool/pytest/test/data/test_sys.txt ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/pytest/test/data/test_sys.txt Sat Aug 27 13:12:04 2005 @@ -0,0 +1,61 @@ +Content-Type: multipart/mixed; boundary="===============1380540766==" +MIME-Version: 1.0 +cpu mhz: unknown +cpu model: unknown +execution-time: 22.5916008949 +exit status: 0 +fspath: /home/contest/xoraxax/pypy-dist/lib-python/modified-2.4.1/test/test_sys.py +options: ['core'] +outcome: OK +platform: linux2 +pypy-revision: 16123 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Thu Aug 18 04:16:48 2005 +testreport-version: 1.1 +timeout: 3364.0 +userhost: xoraxax at tick +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============1380540766== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +test_attributes (__main__.SysModuleTest) ... ok +test_custom_displayhook (__main__.SysModuleTest) ... ok +test_dlopenflags (__main__.SysModuleTest) ... ok +test_exc_clear (__main__.SysModuleTest) ... ok +test_exit (__main__.SysModuleTest) ... ok +test_getdefaultencoding (__main__.SysModuleTest) ... ok +test_getframe (__main__.SysModuleTest) ... ok +test_getwindowsversion (__main__.SysModuleTest) ... ok +test_lost_displayhook (__main__.SysModuleTest) ... ok +test_original_displayhook (__main__.SysModuleTest) ... ok +test_original_excepthook (__main__.SysModuleTest) ... ok +test_recursionlimit (__main__.SysModuleTest) ... ok +test_setcheckinterval (__main__.SysModuleTest) ... ok + +---------------------------------------------------------------------- +Ran 13 tests in 7.241s + +OK + +--===============1380540766== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +faking +Loading grammar /home/contest/xoraxax/pypy-dist/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0xf7fa3068> +fake-wrapping interp file ', mode 'w' at 0xf7fa30b0> +fake-wrapping interp file ', mode 'r' at 0xf7fa3020> + +--===============1380540766==-- \ No newline at end of file Added: pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py Sat Aug 27 13:12:04 2005 @@ -0,0 +1,33 @@ + +import py +#from pypy.tool.pytest.confpath import testresultdir +from pypy.tool.pytest.result import ResultFromMime +testpath = py.path.local( __file__).parts()[-2] +testpath=testpath.join( 'data') + +class TestResultCache: + + def test_timeout(self): + test = ResultFromMime(testpath.join('test___all__.txt')) + assert test.ratio_of_passed() == 0. + + def test_passed(self): + test = ResultFromMime(testpath.join('test_sys.txt')) + assert test.ratio_of_passed() == 1. + + def test_unittest_partial(self): + test = ResultFromMime(testpath.join('test_compile.txt')) + assert test.ratio_of_passed() == 10./15 + + def test_doctest_of(self): + test = ResultFromMime(testpath.join('test_generators.txt')) + assert test.ratio_of_passed() == 133./154 + + def test_doctest_slash(self): + test = ResultFromMime(testpath.join('test_descr.txt')) + assert test.ratio_of_passed() == 65./92 + + def test_fail(self): + test = ResultFromMime(testpath.join('test_global.txt')) + assert test.ratio_of_passed() == 0. + From ericvrp at codespeak.net Sat Aug 27 13:33:12 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 13:33:12 +0200 (CEST) Subject: [pypy-svn] r16743 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050827113312.D5FBC27B47@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 13:33:12 2005 New Revision: 16743 Modified: pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh Log: removed -no-snapshot from shell script, it is no longer used Modified: pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh (original) +++ pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh Sat Aug 27 13:33:12 2005 @@ -1,8 +1,8 @@ export RTYPERORDER=order,module-list.pedronis # stopping on the first error -#python translate_pypy.py -no-c -no-o -text -no-snapshot -fork +#python translate_pypy.py -no-c -no-o -text -fork2 # running it all -python translate_pypy.py target_pypy-llvm -text -no-snapshot -llvm $* +python translate_pypy.py target_pypy-llvm -text -llvm $* # How to work in parallel: Modified: pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh (original) +++ pypy/release/0.7.x/pypy/translator/goal/runtranslate.sh Sat Aug 27 13:33:12 2005 @@ -1,6 +1,6 @@ export RTYPERORDER=order,module-list.pedronis # stopping on the first error -#python translate_pypy.py -no-c -no-o -text -fork +#python translate_pypy.py -no-c -no-o -text -fork # running it all python translate_pypy.py targetpypystandalone -text $* From nik at codespeak.net Sat Aug 27 13:33:28 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 27 Aug 2005 13:33:28 +0200 (CEST) Subject: [pypy-svn] r16744 - pypy/dist/pypy/module/_sre Message-ID: <20050827113328.315F427B47@code1.codespeak.net> Author: nik Date: Sat Aug 27 13:33:27 2005 New Revision: 16744 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: - reenabled an optimization - proved all slice starts non-negative to make the RTyper happy Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Sat Aug 27 13:33:27 2005 @@ -172,7 +172,9 @@ """Creates a new child context of this context and pushes it on the stack. pattern_offset is the offset off the current code position to start interpreting from.""" - pattern_codes = self.pattern_codes[self.code_position + pattern_offset:] + offset = self.code_position + pattern_offset + assert offset >= 0 + pattern_codes = self.pattern_codes[offset:] child_context = MatchContext(self.space, self.state, pattern_codes) self.state.context_stack.append(child_context) self.child_context = child_context @@ -234,8 +236,10 @@ class RepeatContext(MatchContext): def __init__(self, space, context): + offset = context.code_position + assert offset >= 0 MatchContext.__init__(self, space, context.state, - context.pattern_codes[context.code_position:]) + context.pattern_codes[offset:]) self.count = -1 self.previous = context.state.repeat self.last_position = -1 @@ -258,7 +262,9 @@ if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: return fast_search(space, state, pattern_codes) flags = pattern_codes[2] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] + offset = pattern_codes[1] + 1 + assert offset >= 0 + pattern_codes = pattern_codes[offset:] string_position = state.start while string_position <= state.end: @@ -277,9 +283,14 @@ flags = pattern_codes[2] prefix_len = pattern_codes[5] prefix_skip = pattern_codes[6] # don't really know what this is good for + assert prefix_skip >= 0 prefix = pattern_codes[7:7 + prefix_len] - overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] + overlap_offset = 7 + prefix_len - 1 + assert overlap_offset >= 0 + overlap = pattern_codes[overlap_offset:pattern_codes[1] + 1] + pattern_offset = pattern_codes[1] + 1 + assert pattern_offset >= 0 + pattern_codes = pattern_codes[pattern_offset:] i = 0 string_position = state.string_position while string_position < state.end: @@ -316,10 +327,9 @@ def match(space, state, pattern_codes): # Optimization: Check string length. pattern_codes[3] contains the # minimum length for a string to possibly match. - # XXX disabled for now - #if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: - # if state.end - state.string_position < pattern_codes[3]: - # return False + if pattern_codes[0] == OPCODE_INFO and pattern_codes[3] > 0: + if state.end - state.string_position < pattern_codes[3]: + return False state.context_stack.append(MatchContext(space, state, pattern_codes)) has_matched = MatchContext.UNDECIDED while len(state.context_stack) > 0: From ludal at codespeak.net Sat Aug 27 13:37:40 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 27 Aug 2005 13:37:40 +0200 (CEST) Subject: [pypy-svn] r16745 - in pypy/release/0.7.x/pypy: interpreter/pyparser translator/goal Message-ID: <20050827113740.2AAAF27B49@code1.codespeak.net> Author: ludal Date: Sat Aug 27 13:37:36 2005 New Revision: 16745 Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/astbuilder.py pypy/release/0.7.x/pypy/interpreter/pyparser/pythonutil.py pypy/release/0.7.x/pypy/translator/goal/targetcompiler.py pypy/release/0.7.x/pypy/translator/goal/targetparser.py Log: - reflect changes from the -laptop options so the targets don't crash right away - reverted targetparser to using the tuplebuilder since it allows testing the stable pypy parser - remove some dead code Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyparser/astbuilder.py Sat Aug 27 13:37:36 2005 @@ -7,6 +7,7 @@ from pypy.interpreter.astcompiler import ast, consts import pypy.interpreter.pyparser.pysymbol as sym import pypy.interpreter.pyparser.pytoken as tok +from pypy.interpreter.pyparser.error import SyntaxError DEBUG_MODE = 0 Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/pythonutil.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyparser/pythonutil.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyparser/pythonutil.py Sat Aug 27 13:37:36 2005 @@ -52,6 +52,15 @@ return pypy_parse(source, 'exec', lineno) def internal_pypy_parse(source, mode='exec', lineno=False, flags=0): + """This function has no other role than testing the parser's annotation + + annotateme() is basically the same code that pypy_parse(), but with the + following differences : + + - returns a tuplebuilder.StackElement instead of the *real* nested + tuples (StackElement is only a wrapper class around these tuples) + + """ builder = TupleBuilder(PYTHON_PARSER.rules, lineno=False) target_rule = TARGET_DICT[mode] PYTHON_PARSER.parse_source(source, target_rule, builder, flags) @@ -101,20 +110,6 @@ ast = transformer.compile_node(tuples) return ast -def ast_from_input_(input, mode): - builder = AstBuilder() - target = TARGET_DICT[mode] - PYTHON_PARSER.parse_source(input, target, builder) - return builder.rule_stack[-1] - -def ast_compile(input, mode): - from pypy.interpreter.astcompiler import ast, misc, pycodegen - ast_tree = ast_from_input_( input, mode ) - misc.set_filename("", ast_tree) - codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) - code1 = codegenerator.getCode() - return code1 - def target_ast_compile(space, input, mode): from pypy.interpreter.astcompiler import ast, misc, pycodegen builder = AstBuilder(rules=None, debug=0, space=space) @@ -122,7 +117,14 @@ PYTHON_PARSER.parse_source(input, target, builder) ast_tree = builder.rule_stack[-1] misc.set_filename("", ast_tree) - codegenerator = pycodegen.InteractiveCodeGenerator(ast_tree) + if mode=="single": + codegenerator = pycodegen.InteractiveCodeGenerator(space,ast_tree) + elif mode=="eval": + codegenerator = pycodegen.ExpressionCodeGenerator(space,ast_tree) + elif mode=="exec": + codegenerator = pycodegen.ModuleCodeGenerator(space,ast_tree) + else: + raise ValueError("incorrect mode") code1 = codegenerator.getCode() return code1 @@ -135,20 +137,6 @@ return (builder.source_encoding, ast_tree) -## TARGET FOR ANNOTATORS ############################################# -def annotateme(source): - """This function has no other role than testing the parser's annotation - - annotateme() is basically the same code that pypy_parse(), but with the - following differences : - - - returns a tuplebuilder.StackElement instead of the *real* nested - tuples (StackElement is only a wrapper class around these tuples) - - """ - return internal_pypy_parse(source, 'exec') - - if __name__ == "__main__": import sys if len(sys.argv) < 2: Modified: pypy/release/0.7.x/pypy/translator/goal/targetcompiler.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/targetcompiler.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/targetcompiler.py Sat Aug 27 13:37:36 2005 @@ -20,7 +20,7 @@ return target_ast_compile( space, s1, s2 ) # _____ Define and setup target ___ -def target(): +def target(geninterp=True): global space, w_entry_point # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None @@ -28,10 +28,10 @@ # for the poor translator already # XXX why can't I enable this? crashes the annotator! space = StdObjSpace(nofaking=True, - compiler="astparser", + compiler="ast", translating=True, #usemodules=['marhsal', '_sre'], - geninterp=False) + geninterp=geninterp) return entry_point, [str, str] # _____ Run translated _____ Modified: pypy/release/0.7.x/pypy/translator/goal/targetparser.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/targetparser.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/targetparser.py Sat Aug 27 13:37:36 2005 @@ -8,16 +8,13 @@ this_dir = os.path.dirname(sys.argv[0]) -# from pypy.interpreter.pyparser.pythonutil import annotateme +from pypy.interpreter.pyparser.pythonutil import internal_pypy_parse # __________ Entry point __________ -# entry_point = annotateme - -from pypy.interpreter.pyparser.pythonutil import ast_from_input_ -entry_point = ast_from_input_ +entry_point = internal_pypy_parse # _____ Define and setup target ___ -def target(): - return entry_point, [str, str] +def target(*args): + return entry_point, [str, str, bool, int] # _____ Run translated _____ def run(c_entry_point): From arigo at codespeak.net Sat Aug 27 13:50:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 13:50:44 +0200 (CEST) Subject: [pypy-svn] r16746 - pypy/release/0.7.x/pypy/objspace/std Message-ID: <20050827115044.98E1A27B47@code1.codespeak.net> Author: arigo Date: Sat Aug 27 13:50:42 2005 New Revision: 16746 Modified: pypy/release/0.7.x/pypy/objspace/std/longobject.py pypy/release/0.7.x/pypy/objspace/std/marshal_impl.py Log: Reverted a dangerous break of invariant in W_LongObject, about the digits list being allowed to be empty. This allowed two different representations of 0L to exist, and introduced subtle problems (e.g. they don't compare equal). This change is postponed to after the release (as I don't feel like reviewing the whole code for this right now). Related: let's normalize longs that are unmarshalled. Test: marshal.loads(marshal.dumps(0L)) != 0L Modified: pypy/release/0.7.x/pypy/objspace/std/longobject.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/std/longobject.py (original) +++ pypy/release/0.7.x/pypy/objspace/std/longobject.py Sat Aug 27 13:50:42 2005 @@ -90,6 +90,8 @@ W_Object.__init__(w_self, space) #if isinstance(digits, long): #YYYYYY # digits, sign = args_from_long(digits) + if len(digits) == 0: + digits = [0] w_self.digits = DigitArray(digits) w_self.sign = sign w_self.space = space @@ -137,7 +139,7 @@ def _normalize(self): if len(self.digits) == 0: self.sign = 0 - self.digits = [] + self.digits = [0] return i = len(self.digits) - 1 while i != 0 and self.digits[i] == 0: @@ -452,13 +454,13 @@ def neg__Long(space, w_long1): - return W_LongObject(space, w_long1.digits[:], -w_long1.sign) + return W_LongObject(space, w_long1.digits, -w_long1.sign) def pos__Long(space, w_long): return long__Long(space, w_long) def abs__Long(space, w_long): - return W_LongObject(space, w_long.digits[:], abs(w_long.sign)) + return W_LongObject(space, w_long.digits, abs(w_long.sign)) def nonzero__Long(space, w_long): return space.newbool(w_long.sign != 0) Modified: pypy/release/0.7.x/pypy/objspace/std/marshal_impl.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/std/marshal_impl.py (original) +++ pypy/release/0.7.x/pypy/objspace/std/marshal_impl.py Sat Aug 27 13:50:42 2005 @@ -266,7 +266,9 @@ raise_exception(space, 'bad marshal data') digits[i] = digit i += 1 - return W_LongObject(space, digits, sign) + w_long = W_LongObject(space, digits, sign) + w_long._normalize() + return w_long register(TYPE_LONG, unmarshal_Long) # XXX currently, intern() is at applevel, From pedronis at codespeak.net Sat Aug 27 13:56:04 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 27 Aug 2005 13:56:04 +0200 (CEST) Subject: [pypy-svn] r16747 - pypy/release/0.7.x/pypy/module/marshal/test Message-ID: <20050827115604.E02B427B47@code1.codespeak.net> Author: pedronis Date: Sat Aug 27 13:56:03 2005 New Revision: 16747 Modified: pypy/release/0.7.x/pypy/module/marshal/test/test_marshalimpl.py Log: added test about round tripping of 0L and normalization of long internal reprs Modified: pypy/release/0.7.x/pypy/module/marshal/test/test_marshalimpl.py ============================================================================== --- pypy/release/0.7.x/pypy/module/marshal/test/test_marshalimpl.py (original) +++ pypy/release/0.7.x/pypy/module/marshal/test/test_marshalimpl.py Sat Aug 27 13:56:03 2005 @@ -27,3 +27,11 @@ print 'max sys depth = %d, mm_hack = %r, marshal limit = %d' % ( sys.getrecursionlimit(), do_hack, tupdepth) + +class AppTestMarshalMore: + + def test_long_0(self): + import marshal + z = 0L + z1 = marshal.loads(marshal.dumps(z)) + assert z == z1 From rxe at codespeak.net Sat Aug 27 14:00:43 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 27 Aug 2005 14:00:43 +0200 (CEST) Subject: [pypy-svn] r16748 - pypy/release/0.7.x/pypy/objspace/std Message-ID: <20050827120043.15C0427B49@code1.codespeak.net> Author: rxe Date: Sat Aug 27 14:00:42 2005 New Revision: 16748 Modified: pypy/release/0.7.x/pypy/objspace/std/stringobject.py Log: Tentatively check in of an optimisation with respect to string slices - which is assumed (but not proven) to be the root cause of "U" readline() slowness. Modified: pypy/release/0.7.x/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/std/stringobject.py (original) +++ pypy/release/0.7.x/pypy/objspace/std/stringobject.py Sat Aug 27 14:00:42 2005 @@ -938,14 +938,18 @@ return W_StringObject(space, str[ival]) def getitem__String_Slice(space, w_str, w_slice): - # XXX this is really too slow for slices with no step argument w = space.wrap - length = len(w_str._value) + s = w_str._value + length = len(s) start, stop, step, sl = slicetype.indices4(space, w_slice, length) - r = [space.getitem(w_str, w(start + i*step)) for i in range(sl)] - w_r = space.newlist(r) - w_empty = space.newstring([]) - return str_join__String_ANY(space, w_empty, w_r) + if sl == 0: + str = "" + elif step == 1: + assert start >= 0 and stop >= 0 + str = s[start:stop] + else: + str = "".join([s[start + i*step] for i in range(sl)]) + return W_StringObject(space, str) def mul_string_times(space, w_str, w_times): try: From ericvrp at codespeak.net Sat Aug 27 14:01:37 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 14:01:37 +0200 (CEST) Subject: [pypy-svn] r16749 - in pypy/release/0.7.x/pypy/translator/llvm: . module test Message-ID: <20050827120137.AB72E27B49@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 14:01:36 2005 New Revision: 16749 Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py pypy/release/0.7.x/pypy/translator/llvm/module/support.py pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py Log: simplified module/support.py removed test skipping Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Sat Aug 27 14:01:36 2005 @@ -318,6 +318,7 @@ for f in "prepare_and_raise_OverflowError prepare_and_raise_ValueError "\ "prepare_and_raise_ZeroDivisionError prepare_and_raise_IOError "\ + "prepare_ZeroDivisionError prepare_OverflowError prepare_ValueError "\ "RPyString_FromString RPyString_AsString RPyString_Size".split(): extfuncnode.ExternalFuncNode.used_external_functions["%" + f] = True Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/support.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/support.py Sat Aug 27 14:01:36 2005 @@ -5,31 +5,12 @@ declare ccc int %strcmp(sbyte*, sbyte*) declare ccc sbyte* %memset(sbyte*, int, uint) declare ccc sbyte* %strncpy(sbyte *, sbyte *, int) - -%__print_debug_info = internal global bool false -%__print_debug_info_option = internal constant [19 x sbyte] c"--print-debug-info\\00" """ extfunctions = {} -extfunctions["%__debug"] = ((), """ -internal fastcc void %__debug([12 x sbyte]* %msg12) { - %cond = load bool* %__print_debug_info - br bool %cond, label %print_it, label %do_nothing - -do_nothing: - ret void - -print_it: - %msg = getelementptr [12 x sbyte]* %msg12, int 0, int 0 - call int %puts(sbyte* %msg) - ret void -} - -""") - -extfunctions["%RPyString_AsString"] = (("%RPyString_FromString",), """ +extfunctions["%RPyString_AsString"] = ((), """ internal fastcc sbyte* %RPyString_AsString(%RPyString* %structstring) { %source1ptr = getelementptr %RPyString* %structstring, int 0, uint 1, uint 1 %source1 = cast [0 x sbyte]* %source1ptr to sbyte* @@ -97,8 +78,8 @@ #prepare exceptions for exc in "ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL - extfunctions["%%__prepare_%(exc)s" % locals()] = ((), """ -internal fastcc void %%__prepare_%(exc)s() { + extfunctions["%%prepare_%(exc)s" % locals()] = ((), """ +internal fastcc void %%prepare_%(exc)s() { %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%pypy_instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 %%exception_type = load %%RPYTHON_EXCEPTION_VTABLE** %%tmp @@ -129,7 +110,7 @@ %%cond = seteq %s %%y, 0 br bool %%cond, label %%is_0, label %%is_not_0 is_0: - call fastcc void %%__prepare_ZeroDivisionError() + call fastcc void %%prepare_ZeroDivisionError() unwind is_not_0: @@ -145,7 +126,7 @@ %cond2 = setne int %x, -2147483648 br bool %cond2, label %return_block, label %ovf ovf: - call fastcc void %__prepare_OverflowError() + call fastcc void %prepare_OverflowError() unwind """ @@ -157,7 +138,7 @@ for prefix_type_ in "int:int uint:uint".split(): prefix, type_ = prefix_type_.split(':') type_zer_test = zer_test % type_ - extfunctions["%%%(prefix)s_%(func)s" % locals()] = (("%__prepare_ZeroDivisionError",), """ + extfunctions["%%%(prefix)s_%(func)s" % locals()] = ((), """ internal fastcc %(type_)s %%%(prefix)s_%(func)s(%(type_)s %%x, %(type_)s %%y) { %(type_zer_test)s %%z = %(inst)s %(type_)s %%x, %%y @@ -169,7 +150,7 @@ #unary with OverflowError only -extfunctions["%int_neg_ovf"] = (("%__prepare_OverflowError",), """ +extfunctions["%int_neg_ovf"] = ((), """ internal fastcc int %%int_neg_ovf(int %%x) { block1: %%x2 = sub int 0, %%x @@ -179,7 +160,7 @@ } """ % locals()) -extfunctions["%int_abs_ovf"] = (("%__prepare_OverflowError",), """ +extfunctions["%int_abs_ovf"] = ((), """ internal fastcc int %%int_abs_ovf(int %%x) { block0: %%cond1 = setge int %%x, 0 @@ -196,7 +177,7 @@ #binary with OverflowError only -extfunctions["%int_add_ovf"] = (("%__prepare_OverflowError",), """ +extfunctions["%int_add_ovf"] = ((), """ internal fastcc int %%int_add_ovf(int %%x, int %%y) { %%t = add int %%x, %%y %(int_ovf_test)s @@ -206,7 +187,7 @@ } """ % locals()) -extfunctions["%int_sub_ovf"] = (("%__prepare_OverflowError",), """ +extfunctions["%int_sub_ovf"] = ((), """ internal fastcc int %%int_sub_ovf(int %%x, int %%y) { %%t = sub int %%x, %%y %(int_ovf_test)s @@ -216,7 +197,7 @@ } """ % locals()) -extfunctions["%int_mul_ovf"] = (("%__prepare_OverflowError",), """ +extfunctions["%int_mul_ovf"] = ((), """ internal fastcc int %%int_mul_ovf(int %%x, int %%y) { %%t = mul int %%x, %%y %(int_ovf_test)s @@ -229,7 +210,7 @@ #binary with OverflowError and ValueError -extfunctions["%int_lshift_ovf_val"] = (("%__prepare_OverflowError","%__prepare_ValueError"), """ +extfunctions["%int_lshift_ovf_val"] = ((), """ internal fastcc int %%int_lshift_ovf_val(int %%x, int %%y) { %%yu = cast int %%y to ubyte %%t = shl int %%x, ubyte %%yu @@ -243,7 +224,7 @@ #binary with OverflowError and ZeroDivisionError -extfunctions["%int_floordiv_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ +extfunctions["%int_floordiv_ovf_zer"] = ((), """ internal fastcc int %%int_floordiv_ovf_zer(int %%x, int %%y) { %(int_zer_test)s %%t = div int %%x, %%y @@ -254,7 +235,7 @@ } """ % locals()) -extfunctions["%int_mod_ovf_zer"] = (("%__prepare_OverflowError","%__prepare_ZeroDivisionError"), """ +extfunctions["%int_mod_ovf_zer"] = ((), """ internal fastcc int %%int_mod_ovf_zer(int %%x, int %%y) { %(int_zer_test)s %%t = rem int %%x, %%y @@ -265,36 +246,11 @@ } """ % locals()) -extfunctions["%main_noargs"] = [(), """ -int %main(int %argc, sbyte** %argv) { -entry: - br label %no_exit -no_exit: - %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] - %i.0.0 = cast uint %indvar to int - %tmp.8 = getelementptr sbyte** %argv, uint %indvar - %tmp.9 = load sbyte** %tmp.8 - - %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 - %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) - %cond = seteq int %res, 0 - br bool %cond, label %debugging, label %not_debugging - -debugging: - store bool true, bool* %__print_debug_info - br label %next_arg - -not_debugging: - br label %next_arg - -next_arg: - %inc = add int %i.0.0, 1 - %tmp.2 = setlt int %inc, %argc - %indvar.next = add uint %indvar, 1 - br bool %tmp.2, label %no_exit, label %loopexit +# main functions to be moved to genexterns -loopexit: +extfunctions["%main_noargs"] = [(), """ +int %main(int %argc, sbyte** %argv) { %ret = call fastcc int %pypy_main_noargs() ret int %ret } @@ -311,29 +267,14 @@ %i.0.0 = cast uint %indvar to int %tmp.8 = getelementptr sbyte** %argv, uint %indvar %tmp.9 = load sbyte** %tmp.8 - - %t = getelementptr [19 x sbyte]* %__print_debug_info_option, int 0, int 0 - %res = call ccc int %strcmp(sbyte* %tmp.9, sbyte* %t) - %cond = seteq int %res, 0 - br bool %cond, label %debugging, label %not_debugging - -debugging: - store bool true, bool* %__print_debug_info - br label %next_arg - -not_debugging: %rpy = call fastcc %RPyString* %RPyString_FromString(sbyte* %tmp.9) call fastcc void %pypy_ll_append__listPtr_rpy_stringPtr(%RPyListOfString* %pypy_argv, %RPyString* %rpy) - br label %next_arg - -next_arg: %inc = add int %i.0.0, 1 %tmp.2 = setlt int %inc, %argc %indvar.next = add uint %indvar, 1 br bool %tmp.2, label %no_exit, label %loopexit loopexit: - %ret = call fastcc int %pypy_entry_point(%structtype.list* %pypy_argv) ret int %ret } Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py Sat Aug 27 14:01:36 2005 @@ -2,6 +2,7 @@ import sys from pypy.translator.llvm.test.runtest import compile_function from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_lshift +from pypy.translator.test import snippet def test_zerodiv_int(): def zerodiv_int(n): @@ -69,37 +70,32 @@ for i in (-sys.maxint-1, -sys.maxint, 0, sys.maxint-1, sys.maxint): assert f(i) == abs_int_ovf(i) -from pypy.translator.test import snippet +############################ def test_int_overflow(): - py.test.skip("int_add_ovf operation missing (raises)") fn = compile_function(snippet.add_func, [int]) raises(OverflowError, fn, sys.maxint) def test_int_div_ovf_zer(): - py.test.skip("int_floordiv_ovf_zer operation missing (raises)") fn = compile_function(snippet.div_func, [int]) raises(OverflowError, fn, -1) raises(ZeroDivisionError, fn, 0) def test_int_mod_ovf_zer(): - py.test.skip("int_mod_ovf_zer operation missing (raises)") fn = compile_function(snippet.mod_func, [int]) raises(OverflowError, fn, -1) raises(ZeroDivisionError, fn, 0) def test_int_rshift_val(): - py.test.skip("int_rshift_val operation missing (raises)") fn = compile_function(snippet.rshift_func, [int]) raises(ValueError, fn, -1) def test_int_lshift_ovf_val(): - py.test.skip("int_lshift_ovf_val operation missing (raises)") fn = compile_function(snippet.lshift_func, [int]) raises(ValueError, fn, -1) + raises(OverflowError, fn, 1) def test_uint_arith(): - py.test.skip("uint_floordiv_zer operation missing (raises)") def fn(i): try: return ~(i*(i+1))/(i-1) @@ -111,7 +107,6 @@ assert f(i) == fn(i) def test_int_add_ovf(): - py.test.skip("int add incorrect overflow test") def add_func(i): try: return ovfcheck(i + 1) @@ -124,7 +119,6 @@ assert f(sys.maxint) == 123 def test_int_sub_ovf(): - py.test.skip("ovf test") def sub_func(i): try: return ovfcheck(i - 1) @@ -136,25 +130,10 @@ assert f(sys.maxint) == sub_func(sys.maxint) assert f(sys.maxint) == 123 -def test_int_div_ovf_zer(): - py.test.skip("ovf test") - f = compile_function(snippet.div_func) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) - -def test_int_mod_ovf_zer(): - py.test.skip("ovf test") - f = compile_function(snippet.mod_func) - raises(OverflowError, fn, -1) - raises(ZeroDivisionError, fn, 0) - -def test_int_rshift_val(): - py.test.skip("ovf test") - f = compile_function(snippet.rshift_func) - raises(ValueError, fn, -1) - -def test_int_lshift_ovf_val(): - py.test.skip("ovf test") - f = compile_function(snippet.lshift_func) - raises(ValueError, fn, -1) - raises(OverflowError, fn, 1) +def test_shift_with_overflow(self): + shl = compile_function(llvmsnippet.shiftleft, [int, int]) + shr = compile_function(llvmsnippet.shiftright, [int, int]) + for i in [1, 2, 3, 100000, 2000000, sys.maxint - 1]: + for j in [1, 2, 3, 100000, 2000000, sys.maxint - 1]: + assert shl(i, j) == i << j + assert shr(i, j) == i >> j From ludal at codespeak.net Sat Aug 27 14:07:29 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 27 Aug 2005 14:07:29 +0200 (CEST) Subject: [pypy-svn] r16750 - in pypy/release/0.7.x/pypy: interpreter/astcompiler interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050827120729.3C09227B49@code1.codespeak.net> Author: ludal Date: Sat Aug 27 14:07:26 2005 New Revision: 16750 Modified: pypy/release/0.7.x/pypy/interpreter/astcompiler/future.py pypy/release/0.7.x/pypy/interpreter/stablecompiler/future.py pypy/release/0.7.x/pypy/lib/_stablecompiler/future.py Log: fix compiler errors for test_future Modified: pypy/release/0.7.x/pypy/interpreter/astcompiler/future.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/astcompiler/future.py (original) +++ pypy/release/0.7.x/pypy/interpreter/astcompiler/future.py Sat Aug 27 14:07:26 2005 @@ -31,9 +31,14 @@ for name, asname in stmt.names: if name in self.features: self.found[name] = 1 + elif name=="*": + raise SyntaxError( + "future statement does not support import *", + ( stmt.filename, stmt.lineno, 0, "" ) ) else: - raise SyntaxError, \ - "future feature %s is not defined" % name + raise SyntaxError( + "future feature %s is not defined" % name, + ( stmt.filename, stmt.lineno, 0, "" ) ) stmt.valid_future = 1 return 1 return 0 @@ -43,14 +48,17 @@ return self.found.keys() class BadFutureParser(ast.ASTVisitor): - """Check for invalid future statements""" + """Check for invalid future statements + Those not marked valid are appearing after other statements + """ def visitFrom(self, node): if hasattr(node, 'valid_future'): return if node.modname != "__future__": return - raise SyntaxError, "invalid future statement" + raise SyntaxError( "from __future__ imports must occur at the beginning of the file", + ( node.filename, node.lineno, 0, "" ) ) def find_futures(node): p1 = FutureParser() Modified: pypy/release/0.7.x/pypy/interpreter/stablecompiler/future.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/stablecompiler/future.py (original) +++ pypy/release/0.7.x/pypy/interpreter/stablecompiler/future.py Sat Aug 27 14:07:26 2005 @@ -31,9 +31,14 @@ for name, asname in stmt.names: if name in self.features: self.found[name] = 1 + elif name=="*": + raise SyntaxError( + "future statement does not support import *", + ( stmt.filename, stmt.lineno, 0, "" ) ) else: - raise SyntaxError, \ - "future feature %s is not defined" % name + raise SyntaxError( + "future feature %s is not defined" % name, + ( stmt.filename, stmt.lineno, 0, "" ) ) stmt.valid_future = 1 return 1 return 0 @@ -43,14 +48,17 @@ return self.found.keys() class BadFutureParser: - """Check for invalid future statements""" + """Check for invalid future statements + Those not marked valid are appearing after other statements + """ def visitFrom(self, node): if hasattr(node, 'valid_future'): return if node.modname != "__future__": return - raise SyntaxError, "invalid future statement" + raise SyntaxError( "from __future__ imports must occur at the beginning of the file", + ( node.filename, node.lineno, 0, "" ) ) def find_futures(node): p1 = FutureParser() Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/future.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/future.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/future.py Sat Aug 27 14:07:26 2005 @@ -32,9 +32,14 @@ for name, asname in stmt.names: if name in self.features: self.found[name] = 1 + elif name=="*": + raise SyntaxError( + "future statement does not support import *", + ( stmt.filename, stmt.lineno, 0, "" ) ) else: - raise SyntaxError, \ - "future feature %s is not defined" % name + raise SyntaxError( + "future feature %s is not defined" % name, + ( stmt.filename, stmt.lineno, 0, "" ) ) stmt.valid_future = 1 return 1 return 0 @@ -44,14 +49,17 @@ return self.found.keys() class BadFutureParser: - """Check for invalid future statements""" + """Check for invalid future statements + Those not marked valid are appearing after other statements + """ def visitFrom(self, node): if hasattr(node, 'valid_future'): return if node.modname != "__future__": return - raise SyntaxError, "invalid future statement" + raise SyntaxError( "from __future__ imports must occur at the beginning of the file", + ( node.filename, node.lineno, 0, "" ) ) def find_futures(node): p1 = FutureParser() From nik at codespeak.net Sat Aug 27 14:09:36 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 27 Aug 2005 14:09:36 +0200 (CEST) Subject: [pypy-svn] r16752 - pypy/dist/pypy/module/_sre Message-ID: <20050827120936.BEC8527B49@code1.codespeak.net> Author: nik Date: Sat Aug 27 14:09:35 2005 New Revision: 16752 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: uhm, also prove slice stops non-negative ... Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Sat Aug 27 14:09:35 2005 @@ -282,12 +282,15 @@ # <5=length> <6=skip> <7=prefix data> flags = pattern_codes[2] prefix_len = pattern_codes[5] + assert prefix_len >= 0 prefix_skip = pattern_codes[6] # don't really know what this is good for assert prefix_skip >= 0 prefix = pattern_codes[7:7 + prefix_len] overlap_offset = 7 + prefix_len - 1 + overlap_stop = pattern_codes[1] + 1 assert overlap_offset >= 0 - overlap = pattern_codes[overlap_offset:pattern_codes[1] + 1] + assert overlap_stop >= 0 + overlap = pattern_codes[overlap_offset:overlap_stop] pattern_offset = pattern_codes[1] + 1 assert pattern_offset >= 0 pattern_codes = pattern_codes[pattern_offset:] From bea at codespeak.net Sat Aug 27 14:13:01 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sat, 27 Aug 2005 14:13:01 +0200 (CEST) Subject: [pypy-svn] r16754 - pypy/extradoc/sprintinfo Message-ID: <20050827121301.4CE0327B49@code1.codespeak.net> Author: bea Date: Sat Aug 27 14:12:24 2005 New Revision: 16754 Added: pypy/extradoc/sprintinfo/dev_meth_20050827.txt Log: first draft - please read and feedback Added: pypy/extradoc/sprintinfo/dev_meth_20050827.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/dev_meth_20050827.txt Sat Aug 27 14:12:24 2005 @@ -0,0 +1,208 @@ +Distributed and agile development in PyPy + +PyPy isn?t just about producing code - it?s also about how we produce code. +The challenges of coordinating work within a community and making sure it is fused together with +the parts of the project that is EU funded are tricky indeed. Our aim is of course to make sure that the communities +way of working is disturbed as little as possible and that contributing to PyPy still feels fun and interesting (;-) but also +to try to show to the EU as well as other funded projects that open source ideas, tools and methods are really good ways of +running development projects.So the way PyPy as a project is being run - distributed and agile - is something we think might be of use +to other open source development projects and commercial projects. + +Main methods for achieving this is: +-Sprint driven development +-Sync meetings + +Main tools for achieving this is: +-Py-test - automated testing +-Subversion - version control +-Transparent communication and documentation (mailinglists, IRC, tutorials etc etc) + + +Sprint driven development: +-------------------------- + +What is a sprint and why are we sprinting? + +Originally the sprint methodology grew from practices within Zope Corporation. +The definition of a sprint is "two-day or three-day focused development session, +in which developers pair off together in a room and focus on building a particular +subsystem". + +Other typical sprint factors: +- no more than 10 people (although other projects as well as PyPy haven been noted to have more than that. This is the + recommendation and it is probably based on the idea of having a critical mass of people who can interact/communicate and work without adding + the need for more than just the absolute necessary coordination time. The sprints during 2005 have been having ca 13-14 people per sprint, the highest + number of participants during a PyPy sprint has been 20 developers) + +- a coach (the coach is the "manager" of the sprint, he/she sets the goals, prepares, leads and coordinate the work and track progress + and makes this visible for the team. Important to note here - PyPy have never had coaches in our sprints. Instead we hold short + status meetings in the whole group, decisions are made in the same way.So far this have worked well and we still have been able to achieve tremendous results + under stressed conditions, releases and such like. What we do have is a local organizer, often a developer living in the area and one more developer who prepares and organizes sprint. + They do not "manage" the sprint when its started - their role is more of the logistic nature.This doesn?t mean that we wont have use for the coach technique or something similar in the future. ) + +- only coding (this is a tough one. There have been projects who have used the sprinting method to just + visionalize och gather input. PyPy have had a similar brainstorming start up sprint. So far though this is the official line although again, if you visit + a PyPy sprint we are doing quite a lot of other small activities in subgroups as well - planning sprints, documentation, coordinating our EU deliverables and evaluation etc. + But dont worry - our main focus is programming ;-) + +- using XP technicques (mainly pairprogramming and unit testing - PyPy are leaning heavily on these aspects. Pairing up core developers with + people with different levels of knowledge of the codebase have had the results that people can quite quickly get started and join in the development. + Many of hour particpants (new to the project and the codebased) have expressed how pairprogramming in combination with working on the automated tests + have been a great way of getting started.This is of course also a dilemma because our core developers might have to pair up + to solve some extra hairy problems which affects the structure and effect of the other pairs) + +It is a method that fits distributed teams well because it gets the team focused +around clear (and challenging) goals while working collarobative (pairprogramming, status meeting, discussions etc) +as well as accelerated (short increments and tasks, "doing" and testing instead of long start ups of planning and requirement gathering). +This means that most of the time a sprint is a great way of getting results, but also to get new people +aquinted with the codebase. It is also a great method for dissemination and learning within the team because of the pairprogramming. + +If sprinting is combined with actually moving around and having the sprint close to the different active developer groups in +the community as well as during conferences like PyCon and EuroPython, the team will have an easier task of +recruiting new talents to the team. It also vitalizes the community and increases the contact between the different Python implementation projects. + +As always with methodologies you have to adapt them to fit your project (and not the other way around which is much to common). +The PyPy team have been sprinting since early 2003 and have done 12 sprints so far, 11 in Europe and 1 in USA. +Certain practices have proven to be more successful within this team and those are the one we are summarizing here. + +How is it done? + +There are several aspects of a sprint. In the PyPy team we focus on: +1. Content (goal) +2. Venue +3. Information +4. Process + +1. Content (goal) is discussed on mailinglists (pypydev) and on IRC ca 1 month before the event. Beforehand we +have some rough plans called "between sprints" and the sprintplan is based on the status of those issues but also +with a focus on upcoming releases and deliverables. Usually its the core developers who does this +but the transparancy and participation have increased since we started with our weekly "pypy-sync meetings" on IRC. +The sync meetings in combination with a rough in between planning makes it easier for other developer to follow the progress and +thus participating in setting goals for the upcoming sprints. + +The goal need to be challenging or it won?t rally the full effort of the team, but it mustn?t be unrealistic +as that tends to be very frustrating and dissatisfying. It is also very important to take into account the particpants when you set the goal for the sprint. +If the sprint takes place connected to a conference (or similar open events) the goals for the actual coding progress +should be set lower (or handled in another way) and focus should shift to dissemination and getting new/interested people +to a certain understanding of the PyPy codebase. Setting the right goal and making sure this is a shared one is important because it helps the +participants coming in with somewhat similar expectations ;-) + +2. Venue - in the PyPy project we have a rough view on where we are sprinting a few months ahead. No detailed plans have been made that far in advance. +Knowing the dates and the venue makes flight bookings easier ;-) The venue is much more important than one would think. +We need to have a somewhat comfortable environment to work in (where up to 15 people can sit and work), this means tables and chairs, light and electricity outlets. +Is it a venue needing access cards so that only one person is allowed to open? How long can you stay - 24 hours per day or does the landlord want the team evacuated +by 23:00? These are important questions that can gravely affect the "feel and atmosphere" of the sprint as well as the desired results! + +Also, somewhat close to low cost places to eat and accomodate participants. Facilities for making tea/coffe as well as some kind of refrigerator for storing food. +A permanent Internet connection is a must - have the venue were the sprint is planned to be weird rules for access to their network etc etc? + +Whiteboards are useful tools and good to have. Beamers (1-2) are very useful for the status meetings and should be available, at least 1. The project also owns one beamer- +specifically for sprint purposes. + +The person making sure that the requirements for a good sprint venue is being met should therefore have very good local conncetions or, preferrably live their. + +3. Information - discussions about content and goals (pre announcements) are usually carried out on pypy-dev (mailinglist/IRC). All other info is distributed via email on pypy-sprint mailinglist and as webb pages on codespeak. +When dates, venue and content is fully decided a sprint announcement is being made and sent out to pypy-dev and pypy-sprint and updated on codespeak - this happens 2-4 weeks before the sprint. +It?s important that the sprint announcements points to information about local transportation (to the country and to the city and to the venue), currency issues, food and restaurants etc +There are also webbpages in which people announce when they will arrive and where they are accomodated. + +The planning text for the sprint is updated up till the sprint and is then used during the status meetings and between to track work. +After the sprint a sprint report is written by one of the developers and updated to codespeak, this is a kind of summary of the entire sprint and it tells of the work done and the people involved. + +One very important strategy when planning the venue is cost efficiency. Keeping accomodation and food/travel costs as low as possible makes sure that +more people can afford to visit or join the sprint fully. The EU funded parts of the project do have a so called sprint budget which we use to try to help developers to participate in our sprints (travel expenses and accomodation) +and because most of the funding is so called matched funding we pay for most of our expenses in our own organizations and companies anyway. + + +4. Process - a typical PyPy sprint is 3+4 days with a break day in between. Usually sprinters show up the day before the sprint starts. The fist day has a start up meeting, with tutorials of there are participants +new to the project or if some new tool or feature have been implemented. A short presentation of the participants and their background and expectations is also good to do. Unfortunately there is always time spent the first day, +mostly in the morning when people arrive to get the internet and server infrastructure up and running. That is why we are, through documentation, trying to get participants to set up the tools and configurations +needed before they arrive to the sprint. + +Approximate hours being held is 10-17, but people tend to stay longer to code during the evenings. Short status meeting starts up the day and work is "paired" out according to need and wishes. +The PyPy sprints are developer and group driven, because we have no "coach" our status meetings are very much group discussion while notes are taken and our planning texts are updated. +Also - the sprint is done (planned and executed) within the developer group together with someone aqcuainted with the local region (often a developer living there). So within the team there is no one formally responsible for the sprints. +Suggestions for off hours activities and social events for the break day is a good way of emphazising how important it is to take breaks - some pointers in that direction from the local organiziser is good. + +At the end of the sprint we do a technical summary (did we achieve the goals/content), what should be a rough focus for the work until the next sprint and the sprint wheel starts rolling again ;-) +An important aspect is also to evaluate the sprint with the participants. Mostly this is done via emailed questiosn after the sprint, it could also be done as a short group evaluation as well. The reason for evaluating is of course to +get feedback and to make sure that we are not missing opportunities to make our sprints even more efficient and enjoyable. + +The main challenge of our sprint process is the fact that people show up at different dates and leave at different dates. That affects the shared introduction (goals/content, tutorials, presentations etc) +and also the closure - the technical summary etc. Here we are still struggling to find some middle ground - thus increases the importance of feedback. + + +Can I join in? + +Of course. Just follow the work on pypy-dev and if you specifically are interested in information about our sprints - subscribe +to pypy-sprint at codespeak.net and read the news on codespeak for anouncements etc. + +If you think we should sprint in your town - send us an email - we are very interested in using sprints as away of making +contact with active developers (Python/compiler design etc)! + +If you have questions about our sprints and EU-funding - please send an email to pypy-funding at codespeak.net, our mailinglist for project coordination. + +Previous sprints? + +The PyPy team have been sprinting on the following occasions: + +Hildesheim Feb 2003 +Gothenburg May 2003 +LovainLaNeuve June 2003 +Amsterdam Dec 2003 +Europython +/Gothenburg June 2004 +Dublin Oct 2004 +Vilnius Nov 2004 +Leysin Jan 2005 +PyCon +/Washington March 2005 +Europython +/Gothenburg June 2005 +Hildesheim July 2005 +Heidelberg August 2005 + +People how have participated and contributed during our sprints and thus contributing to PyPy: +Armin Rigo +Holger Krekel +Samuele Pedronis +Christian Tismer +Laura Chreighton +Jacob Hall?n +Michael Hudson +Richard Emslie +Anders Chrigstr?m +Alex Martelli +Ludovic Aubry +Adrien DiMascio +Nicholas Chauvat +Niklaus Landemann +Anders Lehmann +Carl Friedrich Bolz +Eric Van Riet Paap +Stephan Diel +Dinu Gherman +Jens-Uwe Mager +Marcus Denker +Bert Freudenberg +Gunther Jantzen +Henrion Benjamin +Godefroid Chapelle +Anna Ravenscroft +Tomek Meka +Jonathan David Riehl +Patrick Maupain +Etienne Posthumus +Nicola Paolucci +Albertas Agejevas +Marius Gedminas +Jesus Cea Avion +Olivier Dormond +Brian Dorsey +Bob Ippolito +Alan McIntyre +Lutz Paelike +Michael Chermside +Beatrice D?ring + + From cfbolz at codespeak.net Sat Aug 27 14:22:57 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 14:22:57 +0200 (CEST) Subject: [pypy-svn] r16755 - in pypy/extradoc: . irclog minute sprintinfo talk talk/pypy-talk-pycon2005 talk/pypy-talk-pycon2005/bubbob Message-ID: <20050827122257.075F027B4B@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 14:22:52 2005 New Revision: 16755 Modified: pypy/extradoc/ (props changed) pypy/extradoc/irclog/ (props changed) pypy/extradoc/irclog/pypy-dev-meeting-06-02-2005.txt (props changed) pypy/extradoc/minute/ (props changed) pypy/extradoc/minute/pypy-sync-07-14-2005.txt (props changed) pypy/extradoc/minute/pypy-sync-07-21-2005.txt (props changed) pypy/extradoc/minute/pypy-sync-07-28-2005.txt (props changed) pypy/extradoc/minute/pypy-sync-08-04-2005.txt (props changed) pypy/extradoc/minute/pypy-sync-08-11-2005.txt (props changed) pypy/extradoc/minute/pypy-sync-08-18-2005.txt (props changed) pypy/extradoc/sprintinfo/ (props changed) pypy/extradoc/sprintinfo/AmsterdamReport.txt (props changed) pypy/extradoc/sprintinfo/EP2005-announcement.txt (props changed) pypy/extradoc/sprintinfo/EP2005-people.txt (props changed) pypy/extradoc/sprintinfo/Heidelberg-sprint.txt (props changed) pypy/extradoc/sprintinfo/VilniusSprintAnnouncement.txt (props changed) pypy/extradoc/sprintinfo/hildesheim2-done.txt (props changed) pypy/extradoc/sprintinfo/hildesheim2-planning.txt (props changed) pypy/extradoc/sprintinfo/post-ep2005-planning.txt (props changed) pypy/extradoc/sprintinfo/pycon_sprint_report.txt (props changed) pypy/extradoc/talk/ (props changed) pypy/extradoc/talk/pypy-ep2005-talk-prep.txt (props changed) pypy/extradoc/talk/pypy-talk-ep2004-hpk.txt (props changed) pypy/extradoc/talk/pypy-talk-pycon2005/ (props changed) pypy/extradoc/talk/pypy-talk-pycon2005/bubbob/ (props changed) pypy/extradoc/to_edu_sig.txt (props changed) Log: fixeol From hpk at codespeak.net Sat Aug 27 14:23:03 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 14:23:03 +0200 (CEST) Subject: [pypy-svn] r16756 - pypy/release/0.7.x Message-ID: <20050827122303.4CB1527B4B@code1.codespeak.net> Author: hpk Date: Sat Aug 27 14:23:02 2005 New Revision: 16756 Modified: pypy/release/0.7.x/README (contents, props changed) Log: add an $Id$ keyword Modified: pypy/release/0.7.x/README ============================================================================== --- pypy/release/0.7.x/README (original) +++ pypy/release/0.7.x/README Sat Aug 27 14:23:02 2005 @@ -1,3 +1,4 @@ +======================================================= PyPy: Python in Python implementation / Version 0.7.0 ======================================================= @@ -31,3 +32,5 @@ Enjoy and send us feedback! the pypy-dev team + +$Id$ From hpk at codespeak.net Sat Aug 27 14:25:21 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 14:25:21 +0200 (CEST) Subject: [pypy-svn] r16757 - pypy/release/0.7.x Message-ID: <20050827122521.9B97327B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 14:25:21 2005 New Revision: 16757 Modified: pypy/release/0.7.x/README (contents, props changed) Log: add HeadURL Modified: pypy/release/0.7.x/README ============================================================================== --- pypy/release/0.7.x/README (original) +++ pypy/release/0.7.x/README Sat Aug 27 14:25:21 2005 @@ -34,3 +34,4 @@ the pypy-dev team $Id$ +$HeadURL$ From cfbolz at codespeak.net Sat Aug 27 14:34:50 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 14:34:50 +0200 (CEST) Subject: [pypy-svn] r16758 - in pypy/release/0.7.x/pypy/module/posix: . test Message-ID: <20050827123450.5751727B49@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 14:34:49 2005 New Revision: 16758 Modified: pypy/release/0.7.x/pypy/module/posix/interp_posix.py pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py Log: test + fix for a bug in unsetenv that crashed the interpreter :-( Modified: pypy/release/0.7.x/pypy/module/posix/interp_posix.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/interp_posix.py (original) +++ pypy/release/0.7.x/pypy/module/posix/interp_posix.py Sat Aug 27 14:34:49 2005 @@ -224,10 +224,11 @@ """unsetenv(key) Delete an environment variable.""" - os.unsetenv(name) - # Remove the key from posix_putenv_garbage; - # this will cause it to be collected. This has to - # happen after the real unsetenv() call because the - # old value was still accessible until then. - del get(space).posix_putenv_garbage[name] + if name in get(space).posix_putenv_garbage: + os.unsetenv(name) + # Remove the key from posix_putenv_garbage; + # this will cause it to be collected. This has to + # happen after the real unsetenv() call because the + # old value was still accessible until then. + del get(space).posix_putenv_garbage[name] unsetenv.unwrap_spec = [ObjSpace, str] Modified: pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py (original) +++ pypy/release/0.7.x/pypy/module/posix/test/test_posix2.py Sat Aug 27 14:34:49 2005 @@ -74,3 +74,31 @@ pass else: raise "did not raise" + +class AppTestEnvironment(object): + def setup_class(cls): + cls.space = space + cls.w_posix = space.appexec([], "(): import %s as m ; return m" % os.name) + cls.w_os = space.appexec([], "(): import os; return os") + cls.w_path = space.wrap(str(path)) + def test_environ(self): + posix = self.posix + os = self.os + + def test_unsetenv_nonexisting(self): + os = self.os + os.unsetenv("XYZABC") #does not raise + try: + os.environ["ABCABC"] + except KeyError: + pass + else: + raise AssertionError("did not raise KeyError") + os.environ["ABCABC"] = "1" + assert os.environ["ABCABC"] == "1" + if hasattr(os, "unsetenv"): + os.unsetenv("ABCABC") + cmd = '''python -c "import os, sys; sys.exit(int('ABCABC' in os.environ))" ''' + res = os.system(cmd) + assert res == 0 + From cfbolz at codespeak.net Sat Aug 27 14:35:33 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 14:35:33 +0200 (CEST) Subject: [pypy-svn] r16759 - in pypy/release/0.7.x/pypy/translator: c tool/pygame Message-ID: <20050827123533.63F0427B49@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 14:35:32 2005 New Revision: 16759 Modified: pypy/release/0.7.x/pypy/translator/c/genc.py pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py Log: typo, discovered when I tried the interactive examples in getting-started Modified: pypy/release/0.7.x/pypy/translator/c/genc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/genc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/genc.py Sat Aug 27 14:35:32 2005 @@ -115,7 +115,7 @@ def translator2database(translator): - pf = pyobjectptr(translator.entrypoint) + pf = lltype.pyobjectptr(translator.entrypoint) db = LowLevelDatabase(translator) db.get(pf) db.complete() Modified: pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py (original) +++ pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py Sat Aug 27 14:35:32 2005 @@ -16,7 +16,7 @@ import py def dot2plain(dotfile, plainfile): - if 0: + if 1: cmdexec('dot -Tplain %s>%s' % (dotfile, plainfile)) elif 0: gw = py.execnet.SshGateway('codespeak.net') From hpk at codespeak.net Sat Aug 27 14:37:40 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 14:37:40 +0200 (CEST) Subject: [pypy-svn] r16760 - pypy/release/0.7.x/pypy/module/sys Message-ID: <20050827123740.2640A27B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 14:37:39 2005 New Revision: 16760 Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py (contents, props changed) Log: add svn-related information via keywords to the sys module. Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/sys/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/sys/__init__.py Sat Aug 27 14:37:39 2005 @@ -51,7 +51,9 @@ 'api_version' : 'space.wrap(1012)', 'version_info' : 'space.wrap((2,4,1, "alpha", 42))', 'version' : 'space.wrap("2.4.1 (pypy 0.7.0 build)")', - 'pypy_version_info' : 'space.wrap((0,7,0, "alpha", 0))', + 'pypy_version_info' : """space.wrap((0,7,0, "alpha", + int('$Revision: 12312$'[11:-1])))""", + 'pypy_svn_url' : 'space.wrap("$HeadURL: qw$"[10:-1])', 'hexversion' : 'space.wrap(0x020401a0)', 'ps1' : 'space.wrap(">>>> ")', 'ps2' : 'space.wrap(".... ")', From hpk at codespeak.net Sat Aug 27 14:38:52 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 14:38:52 +0200 (CEST) Subject: [pypy-svn] r16761 - pypy/release/0.7.x/pypy/module/sys Message-ID: <20050827123852.3F58B27B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 14:38:51 2005 New Revision: 16761 Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py Log: another try at getting the keywords right Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/sys/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/sys/__init__.py Sat Aug 27 14:38:51 2005 @@ -52,8 +52,8 @@ 'version_info' : 'space.wrap((2,4,1, "alpha", 42))', 'version' : 'space.wrap("2.4.1 (pypy 0.7.0 build)")', 'pypy_version_info' : """space.wrap((0,7,0, "alpha", - int('$Revision: 12312$'[11:-1])))""", - 'pypy_svn_url' : 'space.wrap("$HeadURL: qw$"[10:-1])', + int('$Revision$'[11:-1])))""", + 'pypy_svn_url' : 'space.wrap("$HeadURL$"[10:-1])', 'hexversion' : 'space.wrap(0x020401a0)', 'ps1' : 'space.wrap(">>>> ")', 'ps2' : 'space.wrap(".... ")', From cfbolz at codespeak.net Sat Aug 27 14:39:21 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 14:39:21 +0200 (CEST) Subject: [pypy-svn] r16762 - pypy/release/0.7.x/pypy/translator/tool/pygame Message-ID: <20050827123921.9E04227B49@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 14:39:20 2005 New Revision: 16762 Modified: pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py Log: ooooops Modified: pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py (original) +++ pypy/release/0.7.x/pypy/translator/tool/pygame/graphclient.py Sat Aug 27 14:39:20 2005 @@ -16,7 +16,7 @@ import py def dot2plain(dotfile, plainfile): - if 1: + if 0: cmdexec('dot -Tplain %s>%s' % (dotfile, plainfile)) elif 0: gw = py.execnet.SshGateway('codespeak.net') From hpk at codespeak.net Sat Aug 27 14:42:18 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 14:42:18 +0200 (CEST) Subject: [pypy-svn] r16763 - pypy/release/0.7.x/pypy/module/sys Message-ID: <20050827124218.AD88027B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 14:42:18 2005 New Revision: 16763 Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py Log: improving output for pypy_version_info and pypy_svn_url Modified: pypy/release/0.7.x/pypy/module/sys/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/sys/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/sys/__init__.py Sat Aug 27 14:42:18 2005 @@ -53,7 +53,7 @@ 'version' : 'space.wrap("2.4.1 (pypy 0.7.0 build)")', 'pypy_version_info' : """space.wrap((0,7,0, "alpha", int('$Revision$'[11:-1])))""", - 'pypy_svn_url' : 'space.wrap("$HeadURL$"[10:-1])', + 'pypy_svn_url' : 'space.wrap("$HeadURL$"[10:-29])', 'hexversion' : 'space.wrap(0x020401a0)', 'ps1' : 'space.wrap(">>>> ")', 'ps2' : 'space.wrap(".... ")', From ericvrp at codespeak.net Sat Aug 27 14:52:32 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 14:52:32 +0200 (CEST) Subject: [pypy-svn] r16764 - pypy/release/0.7.x/pypy/translator Message-ID: <20050827125232.B02CB27B49@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 14:52:32 2005 New Revision: 16764 Modified: pypy/release/0.7.x/pypy/translator/translator.py Log: fixed t.llvm Modified: pypy/release/0.7.x/pypy/translator/translator.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/translator.py (original) +++ pypy/release/0.7.x/pypy/translator/translator.py Sat Aug 27 14:52:32 2005 @@ -199,11 +199,12 @@ Returns LLVM translation. """ - from pypy.translator.llvm import genllvm + from pypy.translator.llvm.genllvm import GenLLVM if self.annotator is None: raise ValueError, "function has to be annotated." - gen = genllvm.GenLLVM(self) - return str(gen.compile()) + gen = GenLLVM(translator) + filename = gen.gen_llvm_source() + return filename def generatecode(self, gencls, input_arg_types, func): if input_arg_types is None: From cfbolz at codespeak.net Sat Aug 27 14:59:57 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 14:59:57 +0200 (CEST) Subject: [pypy-svn] r16765 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050827125957.763CF27B49@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 14:59:56 2005 New Revision: 16765 Modified: pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py Log: This raises an exception on all targets but targetpypystandalone. For reasons not detailled here this makes the annotator unhappy. Modified: pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/app_basic_example.py Sat Aug 27 14:59:56 2005 @@ -1,6 +1,3 @@ print '--- beginning of app_example.py ---' print 6*7 print '--- end of app_example.py ---' - -import sys -print sys.pypy_translation_info From cfbolz at codespeak.net Sat Aug 27 15:03:04 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 15:03:04 +0200 (CEST) Subject: [pypy-svn] r16766 - in pypy/release/0.7.x/pypy: doc translator Message-ID: <20050827130304.8F32C27B47@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 15:03:03 2005 New Revision: 16766 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt pypy/release/0.7.x/pypy/translator/translator.py Log: (cfbolz, ericvrp fixed printing of llvm code Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 15:03:03 2005 @@ -360,10 +360,17 @@ return type and the arguments of the entry function has to be an int, float or bool. To try it do:: + >>> t = Translator(test.my_gcd) + >>> a = t.annotate([int, int]) + >>> a.simplify() + >>> t.specialize() >>> print t.llvm() + + <... really huge amount of LLVM code ...> + >>> f = t.llvmcompile(optimize=True) - >>> f(28) - 1 + >>> f(15, 10) + 5 In contrast to the C backend this works only for fully annotated and specialized graphs. Modified: pypy/release/0.7.x/pypy/translator/translator.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/translator.py (original) +++ pypy/release/0.7.x/pypy/translator/translator.py Sat Aug 27 15:03:03 2005 @@ -202,9 +202,12 @@ from pypy.translator.llvm.genllvm import GenLLVM if self.annotator is None: raise ValueError, "function has to be annotated." - gen = GenLLVM(translator) + gen = GenLLVM(self) filename = gen.gen_llvm_source() - return filename + f = open(filename, "r") + result = f.read() + f.close() + return result def generatecode(self, gencls, input_arg_types, func): if input_arg_types is None: From bea at codespeak.net Sat Aug 27 15:44:59 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sat, 27 Aug 2005 15:44:59 +0200 (CEST) Subject: [pypy-svn] r16767 - pypy/extradoc/sprintinfo Message-ID: <20050827134459.B385B27B4B@code1.codespeak.net> Author: bea Date: Sat Aug 27 15:44:22 2005 New Revision: 16767 Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt Log: changed the background after feedback... - thanks Holger and Anders L. Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt ============================================================================== --- pypy/extradoc/sprintinfo/dev_meth_20050827.txt (original) +++ pypy/extradoc/sprintinfo/dev_meth_20050827.txt Sat Aug 27 15:44:22 2005 @@ -23,7 +23,7 @@ What is a sprint and why are we sprinting? -Originally the sprint methodology grew from practices within Zope Corporation. +Originally the sprint methodology used in the Python community grew from practices within Zope Corporation. The definition of a sprint is "two-day or three-day focused development session, in which developers pair off together in a room and focus on building a particular subsystem". From cfbolz at codespeak.net Sat Aug 27 16:28:43 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 16:28:43 +0200 (CEST) Subject: [pypy-svn] r16768 - pypy/extradoc/sprintinfo Message-ID: <20050827142843.AC86727B59@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 16:28:42 2005 New Revision: 16768 Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt Log: reformated and fixed typos. Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt ============================================================================== --- pypy/extradoc/sprintinfo/dev_meth_20050827.txt (original) +++ pypy/extradoc/sprintinfo/dev_meth_20050827.txt Sat Aug 27 16:28:42 2005 @@ -1,208 +1,309 @@ -Distributed and agile development in PyPy - -PyPy isn?t just about producing code - it?s also about how we produce code. -The challenges of coordinating work within a community and making sure it is fused together with -the parts of the project that is EU funded are tricky indeed. Our aim is of course to make sure that the communities -way of working is disturbed as little as possible and that contributing to PyPy still feels fun and interesting (;-) but also -to try to show to the EU as well as other funded projects that open source ideas, tools and methods are really good ways of -running development projects.So the way PyPy as a project is being run - distributed and agile - is something we think might be of use -to other open source development projects and commercial projects. - -Main methods for achieving this is: --Sprint driven development --Sync meetings - -Main tools for achieving this is: --Py-test - automated testing --Subversion - version control --Transparent communication and documentation (mailinglists, IRC, tutorials etc etc) - - -Sprint driven development: --------------------------- - -What is a sprint and why are we sprinting? - -Originally the sprint methodology used in the Python community grew from practices within Zope Corporation. -The definition of a sprint is "two-day or three-day focused development session, -in which developers pair off together in a room and focus on building a particular -subsystem". - -Other typical sprint factors: -- no more than 10 people (although other projects as well as PyPy haven been noted to have more than that. This is the - recommendation and it is probably based on the idea of having a critical mass of people who can interact/communicate and work without adding - the need for more than just the absolute necessary coordination time. The sprints during 2005 have been having ca 13-14 people per sprint, the highest - number of participants during a PyPy sprint has been 20 developers) - -- a coach (the coach is the "manager" of the sprint, he/she sets the goals, prepares, leads and coordinate the work and track progress - and makes this visible for the team. Important to note here - PyPy have never had coaches in our sprints. Instead we hold short - status meetings in the whole group, decisions are made in the same way.So far this have worked well and we still have been able to achieve tremendous results - under stressed conditions, releases and such like. What we do have is a local organizer, often a developer living in the area and one more developer who prepares and organizes sprint. - They do not "manage" the sprint when its started - their role is more of the logistic nature.This doesn?t mean that we wont have use for the coach technique or something similar in the future. ) - -- only coding (this is a tough one. There have been projects who have used the sprinting method to just - visionalize och gather input. PyPy have had a similar brainstorming start up sprint. So far though this is the official line although again, if you visit - a PyPy sprint we are doing quite a lot of other small activities in subgroups as well - planning sprints, documentation, coordinating our EU deliverables and evaluation etc. - But dont worry - our main focus is programming ;-) - -- using XP technicques (mainly pairprogramming and unit testing - PyPy are leaning heavily on these aspects. Pairing up core developers with - people with different levels of knowledge of the codebase have had the results that people can quite quickly get started and join in the development. - Many of hour particpants (new to the project and the codebased) have expressed how pairprogramming in combination with working on the automated tests - have been a great way of getting started.This is of course also a dilemma because our core developers might have to pair up - to solve some extra hairy problems which affects the structure and effect of the other pairs) - -It is a method that fits distributed teams well because it gets the team focused -around clear (and challenging) goals while working collarobative (pairprogramming, status meeting, discussions etc) -as well as accelerated (short increments and tasks, "doing" and testing instead of long start ups of planning and requirement gathering). -This means that most of the time a sprint is a great way of getting results, but also to get new people -aquinted with the codebase. It is also a great method for dissemination and learning within the team because of the pairprogramming. - -If sprinting is combined with actually moving around and having the sprint close to the different active developer groups in -the community as well as during conferences like PyCon and EuroPython, the team will have an easier task of -recruiting new talents to the team. It also vitalizes the community and increases the contact between the different Python implementation projects. - -As always with methodologies you have to adapt them to fit your project (and not the other way around which is much to common). -The PyPy team have been sprinting since early 2003 and have done 12 sprints so far, 11 in Europe and 1 in USA. -Certain practices have proven to be more successful within this team and those are the one we are summarizing here. - -How is it done? - -There are several aspects of a sprint. In the PyPy team we focus on: -1. Content (goal) -2. Venue -3. Information -4. Process - -1. Content (goal) is discussed on mailinglists (pypydev) and on IRC ca 1 month before the event. Beforehand we -have some rough plans called "between sprints" and the sprintplan is based on the status of those issues but also -with a focus on upcoming releases and deliverables. Usually its the core developers who does this -but the transparancy and participation have increased since we started with our weekly "pypy-sync meetings" on IRC. -The sync meetings in combination with a rough in between planning makes it easier for other developer to follow the progress and -thus participating in setting goals for the upcoming sprints. - -The goal need to be challenging or it won?t rally the full effort of the team, but it mustn?t be unrealistic -as that tends to be very frustrating and dissatisfying. It is also very important to take into account the particpants when you set the goal for the sprint. -If the sprint takes place connected to a conference (or similar open events) the goals for the actual coding progress -should be set lower (or handled in another way) and focus should shift to dissemination and getting new/interested people -to a certain understanding of the PyPy codebase. Setting the right goal and making sure this is a shared one is important because it helps the -participants coming in with somewhat similar expectations ;-) - -2. Venue - in the PyPy project we have a rough view on where we are sprinting a few months ahead. No detailed plans have been made that far in advance. -Knowing the dates and the venue makes flight bookings easier ;-) The venue is much more important than one would think. -We need to have a somewhat comfortable environment to work in (where up to 15 people can sit and work), this means tables and chairs, light and electricity outlets. -Is it a venue needing access cards so that only one person is allowed to open? How long can you stay - 24 hours per day or does the landlord want the team evacuated -by 23:00? These are important questions that can gravely affect the "feel and atmosphere" of the sprint as well as the desired results! - -Also, somewhat close to low cost places to eat and accomodate participants. Facilities for making tea/coffe as well as some kind of refrigerator for storing food. -A permanent Internet connection is a must - have the venue were the sprint is planned to be weird rules for access to their network etc etc? - -Whiteboards are useful tools and good to have. Beamers (1-2) are very useful for the status meetings and should be available, at least 1. The project also owns one beamer- -specifically for sprint purposes. - -The person making sure that the requirements for a good sprint venue is being met should therefore have very good local conncetions or, preferrably live their. - -3. Information - discussions about content and goals (pre announcements) are usually carried out on pypy-dev (mailinglist/IRC). All other info is distributed via email on pypy-sprint mailinglist and as webb pages on codespeak. -When dates, venue and content is fully decided a sprint announcement is being made and sent out to pypy-dev and pypy-sprint and updated on codespeak - this happens 2-4 weeks before the sprint. -It?s important that the sprint announcements points to information about local transportation (to the country and to the city and to the venue), currency issues, food and restaurants etc -There are also webbpages in which people announce when they will arrive and where they are accomodated. - -The planning text for the sprint is updated up till the sprint and is then used during the status meetings and between to track work. -After the sprint a sprint report is written by one of the developers and updated to codespeak, this is a kind of summary of the entire sprint and it tells of the work done and the people involved. - -One very important strategy when planning the venue is cost efficiency. Keeping accomodation and food/travel costs as low as possible makes sure that -more people can afford to visit or join the sprint fully. The EU funded parts of the project do have a so called sprint budget which we use to try to help developers to participate in our sprints (travel expenses and accomodation) -and because most of the funding is so called matched funding we pay for most of our expenses in our own organizations and companies anyway. - - -4. Process - a typical PyPy sprint is 3+4 days with a break day in between. Usually sprinters show up the day before the sprint starts. The fist day has a start up meeting, with tutorials of there are participants -new to the project or if some new tool or feature have been implemented. A short presentation of the participants and their background and expectations is also good to do. Unfortunately there is always time spent the first day, -mostly in the morning when people arrive to get the internet and server infrastructure up and running. That is why we are, through documentation, trying to get participants to set up the tools and configurations -needed before they arrive to the sprint. - -Approximate hours being held is 10-17, but people tend to stay longer to code during the evenings. Short status meeting starts up the day and work is "paired" out according to need and wishes. -The PyPy sprints are developer and group driven, because we have no "coach" our status meetings are very much group discussion while notes are taken and our planning texts are updated. -Also - the sprint is done (planned and executed) within the developer group together with someone aqcuainted with the local region (often a developer living there). So within the team there is no one formally responsible for the sprints. -Suggestions for off hours activities and social events for the break day is a good way of emphazising how important it is to take breaks - some pointers in that direction from the local organiziser is good. - -At the end of the sprint we do a technical summary (did we achieve the goals/content), what should be a rough focus for the work until the next sprint and the sprint wheel starts rolling again ;-) -An important aspect is also to evaluate the sprint with the participants. Mostly this is done via emailed questiosn after the sprint, it could also be done as a short group evaluation as well. The reason for evaluating is of course to -get feedback and to make sure that we are not missing opportunities to make our sprints even more efficient and enjoyable. - -The main challenge of our sprint process is the fact that people show up at different dates and leave at different dates. That affects the shared introduction (goals/content, tutorials, presentations etc) -and also the closure - the technical summary etc. Here we are still struggling to find some middle ground - thus increases the importance of feedback. - - -Can I join in? - -Of course. Just follow the work on pypy-dev and if you specifically are interested in information about our sprints - subscribe -to pypy-sprint at codespeak.net and read the news on codespeak for anouncements etc. - -If you think we should sprint in your town - send us an email - we are very interested in using sprints as away of making -contact with active developers (Python/compiler design etc)! - -If you have questions about our sprints and EU-funding - please send an email to pypy-funding at codespeak.net, our mailinglist for project coordination. - -Previous sprints? - -The PyPy team have been sprinting on the following occasions: - -Hildesheim Feb 2003 -Gothenburg May 2003 -LovainLaNeuve June 2003 -Amsterdam Dec 2003 -Europython -/Gothenburg June 2004 -Dublin Oct 2004 -Vilnius Nov 2004 -Leysin Jan 2005 -PyCon -/Washington March 2005 -Europython -/Gothenburg June 2005 -Hildesheim July 2005 -Heidelberg August 2005 - -People how have participated and contributed during our sprints and thus contributing to PyPy: -Armin Rigo -Holger Krekel -Samuele Pedronis -Christian Tismer -Laura Chreighton -Jacob Hall?n -Michael Hudson -Richard Emslie -Anders Chrigstr?m -Alex Martelli -Ludovic Aubry -Adrien DiMascio -Nicholas Chauvat -Niklaus Landemann -Anders Lehmann -Carl Friedrich Bolz -Eric Van Riet Paap -Stephan Diel -Dinu Gherman -Jens-Uwe Mager -Marcus Denker -Bert Freudenberg -Gunther Jantzen -Henrion Benjamin -Godefroid Chapelle -Anna Ravenscroft -Tomek Meka -Jonathan David Riehl -Patrick Maupain -Etienne Posthumus -Nicola Paolucci -Albertas Agejevas -Marius Gedminas -Jesus Cea Avion -Olivier Dormond -Brian Dorsey -Bob Ippolito -Alan McIntyre -Lutz Paelike -Michael Chermside -Beatrice D?ring - - +Distributed and agile development in PyPy +========================================= + +PyPy isn't just about producing code - it's also about how we produce code. +The challenges of coordinating work within a community and making sure it is +fused together with the parts of the project that is EU funded are tricky +indeed. Our aim is of course to make sure that the communities way of working +is disturbed as little as possible and that contributing to PyPy still feels +fun and interesting (;-) but also to try to show to the EU as well as other +funded projects that open source ideas, tools and methods are really good ways +of running development projects. So the way PyPy as a project is being run - +distributed and agile - is something we think might be of use to other open +source development projects and commercial projects. + +Main methods for achieving this is: + + * Sprint driven development + * Sync meetings + +Main tools for achieving this is: + + * py.test - automated testing + * Subversion - version control + * Transparent communication and documentation (mailinglists, IRC, tutorials + etc etc) + + +Sprint driven development: +-------------------------- + +What is a sprint and why are we sprinting? + +Originally the sprint methodology grew used in the Python community from +practices within Zope Corporation. The definition of a sprint is "two-day or +three-day focused development session, in which developers pair off together +in a room and focus on building a particular subsystem". + +Other typical sprint factors: + + * no more than 10 people (although other projects as well as PyPy haven been + noted to have more than that. This is the recommendation and it is + probably based on the idea of having a critical mass of people who can + interact/communicate and work without adding the need for more than just + the absolute necessary coordination time. The sprints during 2005 have + been having ca 13-14 people per sprint, the highest number of participants + during a PyPy sprint has been 20 developers) + + * a coach (the coach is the "manager" of the sprint, he/she sets the goals, + prepares, leads and coordinate the work and track progress and makes this + visible for the team. Important to note here - PyPy have never had coaches + in our sprints. Instead we hold short status meetings in the whole group, + decisions are made in the same way.So far this have worked well and we + still have been able to achieve tremendous results under stressed + conditions, releases and such like. What we do have is a local organizer, + often a developer living in the area and one more developer who prepares + and organizes sprint. They do not "manage" the sprint when its started - + their role is more of the logistic nature. This doesn't mean that we wont + have use for the coach technique or something similar in the future). + + * only coding (this is a tough one. There have been projects who have used + the sprinting method to just visionalize och gather input. PyPy have had a + similar brainstorming start up sprint. So far though this is the official + line although again, if you visit a PyPy sprint we are doing quite a lot + of other small activities in subgroups as well - planning sprints, + documentation, coordinating our EU deliverables and evaluation etc. But + dont worry - our main focus is programming ;-) + + * using XP techniques (mainly pairprogramming and unit testing - PyPy is + leaning heavily on these aspects). Pairing up core developers with people + with different levels of knowledge of the codebase have had the results + that people can quite quickly get started and join in the development. + Many of our particpants (new to the project and the codebased) have + expressed how pairprogramming in combination with working on the automated + tests have been a great way of getting started. This is of course also a + dilemma because our core developers might have to pair up to solve some + extra hairy problems which affects the structure and effect of the other + pairs. + +It is a method that fits distributed teams well because it gets the team +focused around clear (and challenging) goals while working collarobative +(pairprogramming, status meeting, discussions etc) as well as accelerated +(short increments and tasks, "doing" and testing instead of long start ups of +planning and requirement gathering). This means that most of the time a sprint +is a great way of getting results, but also to get new people aquinted with +the codebase. It is also a great method for dissemination and learning within +the team because of the pairprogramming. + +If sprinting is combined with actually moving around and having the sprint +close to the different active developer groups in the community as well as +during conferences like PyCon and EuroPython, the team will have an easier +task of recruiting new talents to the team. It also vitalizes the community +and increases the contact between the different Python implementation +projects. + +As always with methodologies you have to adapt them to fit your project (and +not the other way around which is much too common). The PyPy team have been +sprinting since early 2003 and have done 12 sprints so far, 11 in Europe and 1 +in the USA. Certain practices have proven to be more successful within this +team and those are the one we are summarizing here. + + +How is it done? ++++++++++++++++ + +There are several aspects of a sprint. In the PyPy team we focus on: +1. Content (goal) +2. Venue +3. Information +4. Process + +1. Content (goal) is discussed on mailinglists (pypy-dev) and on IRC ca one + month before the event. Beforehand we have some rough plans called "between + sprints" and the sprintplan is based on the status of those issues but also + with a focus on upcoming releases and deliverables. Usually its the core + developers who does this but the transparancy and participation have + increased since we started with our weekly "pypy-sync meetings" on IRC. The + sync meetings in combination with a rough in between planning makes it + easier for other developer to follow the progress and thus participating in + setting goals for the upcoming sprints. + + The goal needs to be challenging or it won't rally the full effort of the + team, but it must not be unrealistic as that tends to be very frustrating + and dissatisfying. It is also very important to take into account the + particpants when you set the goal for the sprint. If the sprint takes place + connected to a conference (or similar open events) the goals for the actual + coding progress should be set lower (or handled in another way) and focus + should shift to dissemination and getting new/interested people to a + certain understanding of the PyPy codebase. Setting the right goal and + making sure this is a shared one is important because it helps the + participants coming in with somewhat similar expectations ;-) + +2. Venue - in the PyPy project we have a rough view on where we are sprinting + a few months ahead. No detailed plans have been made that far in + advance. Knowing the dates and the venue makes flight bookings easier ;-) + The venue is much more important than one would think. We need to have a + somewhat comfortable environment to work in (where up to 15 people can sit + and work), this means tables and chairs, light and electricity outlets. Is + it a venue needing access cards so that only one person is allowed to open? + How long can you stay - 24 hours per day or does the landlord want the team + evacuated by 23:00? These are important questions that can gravely affect + the "feel and atmosphere" of the sprint as well as the desired results! + + Also, somewhat close to low cost places to eat and accomodate + participants. Facilities for making tea/coffe as well as some kind of + refrigerator for storing food. A permanent Internet connection is a must - + has the venue were the sprint is planned to be weird rules for access to + their network etc etc? + + Whiteboards are useful tools and good to have. Beamers (1-2) are very + useful for the status meetings and should be available, at least 1. The + project also owns one beamer - specifically for sprint purposes. + + The person making sure that the requirements for a good sprint venue is + being met should therefore have very good local conncetions or, preferrably + live there. + +3. Information - discussions about content and goals (pre announcements) are + usually carried out on pypy-dev (mailinglist/IRC). All other info is + distributed via email on pypy-sprint mailinglist and as web pages on + codespeak. When dates, venue and content is fully decided a sprint + announcement is being made and sent out to pypy-dev and pypy-sprint as well + as more general purpose mailing lists like comp.lang.python and updated on + codespeak - this happens 2-4 weeks before the sprint. It's important that + the sprint announcements points to information about local transportation + (to the country and to the city and to the venue), currency issues, food + and restaurants etc. There are also webpages in which people announce when + they will arrive and where they are accomodated. + + The planning text for the sprint is updated up till the sprint and is then + used during the status meetings and between to track work. After the sprint + (or even better: in between so that the memory is fresh) a sprint report is + written by one of the developers and updated to codespeak, this is a kind + of summary of the entire sprint and it tells of the work done and the + people involved. + + One very important strategy when planning the venue is cost + efficiency. Keeping accomodation and food/travel costs as low as possible + makes sure that more people can afford to visit or join the sprint + fully. The EU funded parts of the project do have a so called sprint budget + which we use to try to help developers to participate in our sprints + (travel expenses and accomodation) and because most of the funding is so + called matched funding we pay for most of our expenses in our own + organizations and companies anyway. + + +4. Process - a typical PyPy sprint is 7 days with a break day in the + middle. Usually sprinters show up the day before the sprint starts. The + first day has a start up meeting, with tutorials of there are participants + new to the project or if some new tool or feature have been implemented. A + short presentation of the participants and their background and + expectations is also good to do. Unfortunately there is always time spent + the first day, mostly in the morning when people arrive to get the internet + and server infrastructure up and running. That is why we are, through + documentation_, trying to get participants to set up the tools and + configurations needed before they arrive to the sprint. + + Approximate hours being held are 10-17, but people tend to stay longer to + code during the evenings. A short status meeting starts up the day and work + is "paired" out according to need and wishes. The PyPy sprints are + developer and group driven, because we have no "coach" our status meetings + are very much group discussion while notes are taken and our planning texts + are updated. Also - the sprint is done (planned and executed) within the + developer group together with someone acquainted with the local region + (often a developer living there). So within the team there is no one + formally responsible for the sprints. + + Suggestions for off hours activities and social events for the break day is + a good way of emphazising how important it is to take breaks - some + pointers in that direction from the local organiziser is good. + + At the end of the sprint we do a technical summary (did we achieve the + goals/content), what should be a rough focus for the work until the next + sprint and the sprint wheel starts rolling again ;-) An important aspect is + also to evaluate the sprint with the participants. Mostly this is done via + emailed questions after the sprint, it could also be done as a short group + evaluation as well. The reason for evaluating is of course to get feedback + and to make sure that we are not missing opportunities to make our sprints + even more efficient and enjoyable. + + The main challenge of our sprint process is the fact that people show up + at different dates and leave at different dates. That affects the shared + introduction (goals/content, tutorials, presentations etc) and also the + closure - the technical summary etc. Here we are still struggling to find + some middle ground - thus increases the importance of feedback. + + +.. _documentation: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html + +Can I join in? +++++++++++++++ + +Of course. Just follow the work on pypy-dev and if you specifically are +interested in information about our sprints - subscribe to +pypy-sprint at codespeak.net and read the news on codespeak for anouncements etc. + +If you think we should sprint in your town - send us an email - we are very +interested in using sprints as away of making contact with active developers +(Python/compiler design etc)! + +If you have questions about our sprints and EU-funding - please send an email +to pypy-funding at codespeak.net, our mailinglist for project coordination. + +Previous sprints? ++++++++++++++++++ + +The PyPy team have been sprinting on the following occasions:: + + Hildesheim Feb 2003 + Gothenburg May 2003 + LovainLaNeuve June 2003 + Amsterdam Dec 2003 + Europython + /Gothenburg June 2004 + Dublin Oct 2004 + Vilnius Nov 2004 + Leysin Jan 2005 + PyCon + /Washington March 2005 + Europython + /Gothenburg June 2005 + Hildesheim July 2005 + Heidelberg August 2005 + +People how have participated and contributed during our sprints and thus +contributing to PyPy:: + + Armin Rigo + Holger Krekel + Samuele Pedronis + Christian Tismer + Laura Chreighton + Jacob Hall??n + Michael Hudson + Richard Emslie + Anders Chrigstr??m + Alex Martelli + Ludovic Aubry + Adrien DiMascio + Nicholas Chauvat + Niklaus Landemann + Anders Lehmann + Carl Friedrich Bolz + Eric Van Riet Paap + Stephan Diel + Dinu Gherman + Jens-Uwe Mager + Marcus Denker + Bert Freudenberg + Gunther Jantzen + Henrion Benjamin + Godefroid Chapelle + Anna Ravenscroft + Tomek Meka + Jonathan David Riehl + Patrick Maupain + Etienne Posthumus + Nicola Paolucci + Albertas Agejevas + Marius Gedminas + Jesus Cea Avion + Olivier Dormond + Brian Dorsey + Bob Ippolito + Alan McIntyre + Lutz Paelike + Michael Chermside + Beatrice D??ring + + From hpk at codespeak.net Sat Aug 27 16:32:29 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 16:32:29 +0200 (CEST) Subject: [pypy-svn] r16769 - pypy/release/0.7.x/pypy/tool/pytest Message-ID: <20050827143229.E6E3527B5B@code1.codespeak.net> Author: hpk Date: Sat Aug 27 16:32:29 2005 New Revision: 16769 Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py pypy/release/0.7.x/pypy/tool/pytest/result.py Log: show more detailed compliancy test information with the new result-parsing help from ale. Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py Sat Aug 27 16:32:29 2005 @@ -29,7 +29,7 @@ def render_latest_table(self, results): table = html.table( [html.th(x, align='left') - for x in ("status", "filename", "revision", + for x in ("failure", "filename", "revision", "user", "platform", "elapsed", "options", "last error line" )], @@ -54,8 +54,9 @@ if not options: options=" " + failureratio = 1.0 - result.ratio_of_passed() return html.tr( - html.td(result['outcome'], + html.td("%.2f%%" % failureratio, style = "background-color: %s" % (getresultcolor(result),)), html.td(self.render_test_references(result)), html.td(result['pypy-revision']), @@ -119,11 +120,17 @@ ok = len([x for x in tests if x.isok()]) err = len([x for x in tests if x.iserror()]) to = len([x for x in tests if x.istimeout()]) - sum = ok + err + to - sum100 = sum / 100.0 + numtests = ok + err + to + t = html.table() + sum100 = numtests / 100.0 def row(*args): return html.tr(*[html.td(arg) for arg in args]) + + sum_passed = sum([x.ratio_of_passed() for x in tests]) + t.append(row(html.b("core tests compliancy"), + html.b("%.2f%%" % (sum_passed/sum100,)))) + t.append(row("testmodules passed completely", "%.2f%%" % (ok/sum100))) t.append(row("testmodules (partially) failed", "%.2f%%" % (err/sum100))) t.append(row("testmodules timeout", "%.2f%%" % (to/sum100))) Modified: pypy/release/0.7.x/pypy/tool/pytest/result.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/result.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/result.py Sat Aug 27 16:32:29 2005 @@ -91,10 +91,10 @@ return passed/run else: run = self.grep_nr('TestFailed: \d+ of ',section='stderr') - if run >0 : + if run > 0 : return (run-passed)/run else: - return 0 + return 0.0 def isok(self): return self['outcome'].lower() == 'ok' From pedronis at codespeak.net Sat Aug 27 16:33:20 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 27 Aug 2005 16:33:20 +0200 (CEST) Subject: [pypy-svn] r16770 - pypy/release/0.7.x/pypy/translator/c/src Message-ID: <20050827143320.AA03B27B5E@code1.codespeak.net> Author: pedronis Date: Sat Aug 27 16:33:19 2005 New Revision: 16770 Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Log: unsetenv on some platform is void, it seems CPython posix also ignores its return value Modified: pypy/release/0.7.x/pypy/translator/c/src/ll_os.h ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/src/ll_os.h (original) +++ pypy/release/0.7.x/pypy/translator/c/src/ll_os.h Sat Aug 27 16:33:19 2005 @@ -218,10 +218,7 @@ #ifdef HAVE_UNSETENV void LL_os_unsetenv(RPyString * name) { - int error = unsetenv(RPyString_AsString(name)); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - } + unsetenv(RPyString_AsString(name)); } #endif From arigo at codespeak.net Sat Aug 27 16:36:04 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 16:36:04 +0200 (CEST) Subject: [pypy-svn] r16771 - in pypy/release/0.7.x/pypy/interpreter: . pyparser Message-ID: <20050827143604.4C3DE27B64@code1.codespeak.net> Author: arigo Date: Sat Aug 27 16:35:53 2005 New Revision: 16771 Modified: pypy/release/0.7.x/pypy/interpreter/pycompiler.py pypy/release/0.7.x/pypy/interpreter/pyparser/pythonlexer.py Log: compile(): * look for the BOM (byte-order marker) for utf-8 * raise ValueError if invalid flags are passed Modified: pypy/release/0.7.x/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pycompiler.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pycompiler.py Sat Aug 27 16:35:53 2005 @@ -86,11 +86,15 @@ flag = getattr(__future__, fname).compiler_flag compiler_flags |= flag compiler_features[fname] = flag +allowed_flags = compiler_flags | PyCF_DONT_IMPLY_DEDENT -def get_flag_names( flag ): +def get_flag_names(space, flags): + if flags & ~allowed_flags: + raise OperationError(space.w_ValueError, + space.wrap("compile(): unrecognized flags")) flag_names = [] for name, value in compiler_features.items(): - if flag & value: + if flags & value: flag_names.append( name ) return flag_names @@ -221,7 +225,7 @@ transformer = Transformer(filename) tree = transformer.compile_node(tuples) stablecompiler.misc.set_filename(filename, tree) - flag_names = get_flag_names( flags ) + flag_names = get_flag_names(space, flags) if mode == 'exec': codegenerator = ModuleCodeGenerator(tree, flag_names) elif mode == 'single': @@ -317,7 +321,7 @@ return PythonCompiler.compile_parse_result(self, parse_result, filename, mode, flags) source_encoding, stack_element = parse_result - flag_names = get_flag_names( flags ) + flag_names = get_flag_names(space, flags) w_flag_names = space.newlist( [ space.wrap(n) for n in flag_names ] ) w_nested_tuples = stack_element.as_w_tuple(space, lineno=True) if source_encoding is not None: @@ -341,7 +345,7 @@ def fakecompile(self, source, filename, mode, flags): flags |= __future__.generators.compiler_flag # always on (2.2 compat) - flag_names = get_flag_names(flags) + flag_names = get_flag_names(self.space, flags) space = self.space w_flag_names = space.newlist( [ space.wrap(n) for n in flag_names ] ) @@ -410,7 +414,7 @@ space = self.space try: astcompiler.misc.set_filename(filename, ast_tree) - flag_names = get_flag_names( flags ) + flag_names = get_flag_names(space, flags) if mode == 'exec': codegenerator = ModuleCodeGenerator(space, ast_tree, flag_names) elif mode == 'single': @@ -458,7 +462,7 @@ def compile(self, source, filename, mode, flags): flags |= __future__.generators.compiler_flag # always on (2.2 compat) - flag_names = get_flag_names(flags) + flag_names = get_flag_names(self.space, flags) space = self.space return None Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyparser/pythonlexer.py Sat Aug 27 16:35:53 2005 @@ -116,6 +116,13 @@ # make the annotator happy pos = -1 lines.append('') # XXX HACK probably not needed + + # look for the bom (byte-order marker) for utf-8 + # XXX encoding support is incomplete at the moment + if lines[0].startswith('\xEF\xBB\xBF'): + lines[0] = lines[0][3:] + encoding = 'utf-8' + # make the annotator happy endDFA = automata.DFA([], []) # make the annotator happy From pedronis at codespeak.net Sat Aug 27 16:36:10 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 27 Aug 2005 16:36:10 +0200 (CEST) Subject: [pypy-svn] r16772 - in pypy/release/0.7.x/pypy: annotation translator/test Message-ID: <20050827143610.500FE27B6D@code1.codespeak.net> Author: pedronis Date: Sat Aug 27 16:36:08 2005 New Revision: 16772 Modified: pypy/release/0.7.x/pypy/annotation/bookkeeper.py pypy/release/0.7.x/pypy/translator/test/test_annrpython.py Log: sanity check added: be not pleased with prebuilt instances of classes needing specialization Modified: pypy/release/0.7.x/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/release/0.7.x/pypy/annotation/bookkeeper.py (original) +++ pypy/release/0.7.x/pypy/annotation/bookkeeper.py Sat Aug 27 16:36:08 2005 @@ -369,7 +369,9 @@ return self.getpbc(x) else: clsdef = self.getclassdef(x.__class__) - + if x.__class__.__dict__.get('_annspecialcase_', '').endswith('ctr_location'): + print "encountered a pre-built mutable instance of a class needing specialization: %s" % x.__class__.__name__ + raise Exception, "encountered a pre-built mutable instance of a class needing specialization: %s" % x.__class__.__name__ if x not in self.seen_mutable: # avoid circular reflowing, # see for example test_circular_mutable_getattr self.seen_mutable[x] = True Modified: pypy/release/0.7.x/pypy/translator/test/test_annrpython.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/test/test_annrpython.py (original) +++ pypy/release/0.7.x/pypy/translator/test/test_annrpython.py Sat Aug 27 16:36:08 2005 @@ -605,6 +605,13 @@ assert s.items[0].knowntype == int assert s.items[1].knowntype == str + def test_class_spec_confused(self): + x = snippet.PolyStk() + def f(): + return x + a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy()) + py.test.raises(Exception, a.build_types, f, []) + def test_exception_deduction_with_raise1(self): a = self.RPythonAnnotator() s = a.build_types(snippet.exception_deduction_with_raise1, [bool]) From hpk at codespeak.net Sat Aug 27 16:37:25 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 16:37:25 +0200 (CEST) Subject: [pypy-svn] r16773 - pypy/release/0.7.x/pypy/tool/pytest Message-ID: <20050827143725.8986C27B68@code1.codespeak.net> Author: hpk Date: Sat Aug 27 16:37:25 2005 New Revision: 16773 Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py Log: actually show 100% instead of 1% Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py Sat Aug 27 16:37:25 2005 @@ -54,7 +54,7 @@ if not options: options=" " - failureratio = 1.0 - result.ratio_of_passed() + failureratio = 100 * (1.0 - result.ratio_of_passed()) return html.tr( html.td("%.2f%%" % failureratio, style = "background-color: %s" % (getresultcolor(result),)), @@ -129,7 +129,7 @@ sum_passed = sum([x.ratio_of_passed() for x in tests]) t.append(row(html.b("core tests compliancy"), - html.b("%.2f%%" % (sum_passed/sum100,)))) + html.b("%.2f%%" % (sum_passed/sum100*100,)))) t.append(row("testmodules passed completely", "%.2f%%" % (ok/sum100))) t.append(row("testmodules (partially) failed", "%.2f%%" % (err/sum100))) From hpk at codespeak.net Sat Aug 27 16:41:05 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 16:41:05 +0200 (CEST) Subject: [pypy-svn] r16774 - pypy/release/0.7.x/pypy/tool/pytest Message-ID: <20050827144105.1191727B6D@code1.codespeak.net> Author: hpk Date: Sat Aug 27 16:41:04 2005 New Revision: 16774 Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py Log: aehem, what about thinking before chekcing in. Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py Sat Aug 27 16:41:04 2005 @@ -129,7 +129,7 @@ sum_passed = sum([x.ratio_of_passed() for x in tests]) t.append(row(html.b("core tests compliancy"), - html.b("%.2f%%" % (sum_passed/sum100*100,)))) + html.b("%.2f%%" % (sum_passed/sum100,)))) t.append(row("testmodules passed completely", "%.2f%%" % (ok/sum100))) t.append(row("testmodules (partially) failed", "%.2f%%" % (err/sum100))) From arigo at codespeak.net Sat Aug 27 17:02:17 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 17:02:17 +0200 (CEST) Subject: [pypy-svn] r16776 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050827150217.0A6F127B73@code1.codespeak.net> Author: arigo Date: Sat Aug 27 17:02:15 2005 New Revision: 16776 Modified: pypy/release/0.7.x/pypy/translator/goal/app_main.py Log: Don't crash on string exceptions in the debug message. Modified: pypy/release/0.7.x/pypy/translator/goal/app_main.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/app_main.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/app_main.py Sat Aug 27 17:02:15 2005 @@ -61,7 +61,8 @@ # XXX extra debugging info in case the code below goes very wrong # XXX (temporary) if hasattr(sys, 'stderr'): - print >> sys.stderr, "debug: exception-type: ", etype.__name__ + s = getattr(etype, '__name__', repr(etype)) + print >> sys.stderr, "debug: exception-type: ", s print >> sys.stderr, "debug: exception-value:", str(evalue) tbentry = etraceback if tbentry: From cfbolz at codespeak.net Sat Aug 27 17:14:06 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 17:14:06 +0200 (CEST) Subject: [pypy-svn] r16777 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827151406.30FCC27B75@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 17:14:05 2005 New Revision: 16777 Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Log: some small refinements Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/release-0.7.0.txt (original) +++ pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Sat Aug 27 17:14:05 2005 @@ -2,7 +2,7 @@ ============================================================== The PyPy Development Team is happy to announce its first -public release of a fully translated self contained Python +public release of a fully translatable self contained Python implementation. The 0.7 release is a preview release showcasing the results of our efforts in the last few months: @@ -11,7 +11,7 @@ - the ability to translate with thread support or without -- a translation choice of using a refcounting or Boehm +- a translation choice of using a reference counting or Boehm garbage collector - very high compliancy with Python 2.4.1 (fully based on From cfbolz at codespeak.net Sat Aug 27 17:16:41 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 17:16:41 +0200 (CEST) Subject: [pypy-svn] r16778 - pypy/release/0.7.x/pypy/translator/c/test Message-ID: <20050827151641.2BE7927B7A@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 17:16:40 2005 New Revision: 16778 Modified: pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Log: this test failed if run alone. humph Modified: pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Sat Aug 27 17:16:40 2005 @@ -437,6 +437,19 @@ # XXX missing test for unsetenv, please do this on Linux + +# aaargh: bad idea: the above test updates the environment directly, so the +# os.environ dict is not updated, which makes the following test fail if not run +# allone. therefor it is neccessary to use execnet. + +test_src = """import py +import os, time +from pypy.tool.udir import udir +from pypy.translator.c.test.test_genc import compile +from pypy.translator.c.extfunc import EXTERNALS +from pypy.rpython import ros + + def test_environ(): def env(idx): # need to as if the result is NULL, or we crash @@ -450,4 +463,17 @@ if not func(count): break count += 1 - assert count == len(os.environ.keys()) + return count == len(os.environ.keys()) + +def run_test(func): + channel.send(func()) +run_test(test_environ) +""" + +def test_environ(): + import py + gw = py.execnet.PopenGateway() + chan = gw.remote_exec(py.code.Source(test_src)) + res = chan.receive() + assert res + chan.close() From rxe at codespeak.net Sat Aug 27 17:18:17 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 27 Aug 2005 17:18:17 +0200 (CEST) Subject: [pypy-svn] r16779 - in pypy/release/0.7.x/pypy/translator/llvm: . module Message-ID: <20050827151817.3426F27B7C@code1.codespeak.net> Author: rxe Date: Sat Aug 27 17:18:16 2005 New Revision: 16779 Modified: pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py pypy/release/0.7.x/pypy/translator/llvm/genllvm.py pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c Log: Get rid of hardcoded struct type in genexterns.c and make it look as close as we can to genc c code. (ericvrp/rxe) Modified: pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/extfuncnode.py Sat Aug 27 17:18:16 2005 @@ -9,7 +9,10 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = self.make_ref("%", value._callable.__name__) + name = value._callable.__name__ + assert name.startswith("ll") + name = "LL" + name[2:] + self.ref = self.make_ref("%", name) def getdecl(self): T = self.value._TYPE Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Sat Aug 27 17:18:16 2005 @@ -154,7 +154,8 @@ for c_name, obj in extern_decls: if isinstance(obj, lltype.LowLevelType): - pass + s = "#define %s struct %s\n%s;\n" % (c_name, c_name, c_name) + ccode.append(s) elif isinstance(obj, types.FunctionType): funcptr = getfunctionptr(self.translator, obj) c = inputconst(lltype.typeOf(funcptr), funcptr) Modified: pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c Sat Aug 27 17:18:16 2005 @@ -1,25 +1,18 @@ -// Forward declare hacks -struct RPyFREXP_RESULT; -struct RPyMODF_RESULT; -struct RPyString; -struct RPySTAT_RESULT; -struct RPyListOfString; +char *RPyString_AsString(RPyString*); +int RPyString_Size(RPyString*); +RPyString *RPyString_FromString(char *); + +// Generated by rpython - argggh have to feed in prototypes +RPyFREXP_RESULT *ll_frexp_result(double, int); +RPyMODF_RESULT *ll_modf_result(double, double); +RPySTAT_RESULT *ll_stat_result(int, int, int, int, int, int, int, int, int, int); +void RPYTHON_RAISE_OSERROR(int error); // We hand craft these in module/support.ll void prepare_and_raise_OverflowError(char *); void prepare_and_raise_ValueError(char *); void prepare_and_raise_IOError(char *); -char *RPyString_AsString(struct RPyString*); -int RPyString_Size(struct RPyString*); -struct RPyString *RPyString_FromString(char *); - -// Generated by rpython - argggh have to feed in prototypes -struct RPyFREXP_RESULT *ll_frexp_result(double, int); -struct RPyMODF_RESULT *ll_modf_result(double, double); -struct RPySTAT_RESULT *ll_stat_result(int, int, int, int, int, int, int, int, int, int); -void RPYTHON_RAISE_OSERROR(int error); -int pypy_entry_point(struct RPyListOfString*); #include #include @@ -28,7 +21,7 @@ #define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW -int ll_math_is_error(double x) { +int LL_math_is_error(double x) { if (errno == ERANGE) { if (!x) return 0; @@ -43,12 +36,12 @@ #define LL_MATH_CHECK_ERROR(x, errret) do { \ LL_MATH_SET_ERANGE_IF_MATH_ERROR(x); \ - if (errno && ll_math_is_error(x)) \ + if (errno && LL_math_is_error(x)) \ return errret; \ } while(0) -double ll_math_pow(double x, double y) { +double LL_math_pow(double x, double y) { double r; LL_MATH_ERROR_RESET; r = pow(x, y); @@ -56,7 +49,7 @@ return r; } -double ll_math_atan2(double x, double y) { +double LL_math_atan2(double x, double y) { double r; LL_MATH_ERROR_RESET; r = atan2(x, y); @@ -64,7 +57,7 @@ return r; } -double ll_math_fmod(double x, double y) { +double LL_math_fmod(double x, double y) { double r; LL_MATH_ERROR_RESET; r = fmod(x, y); @@ -72,7 +65,7 @@ return r; } -double ll_math_ldexp(double x, long y) { +double LL_math_ldexp(double x, long y) { double r; LL_MATH_ERROR_RESET; r = ldexp(x, (int) y); @@ -80,7 +73,7 @@ return r; } -double ll_math_hypot(double x, double y) { +double LL_math_hypot(double x, double y) { double r; LL_MATH_ERROR_RESET; r = hypot(x, y); @@ -88,7 +81,7 @@ return r; } -struct RPyMODF_RESULT* ll_math_modf(double x) { +RPyMODF_RESULT* LL_math_modf(double x) { double intpart, fracpart; LL_MATH_ERROR_RESET; fracpart = modf(x, &intpart); @@ -98,7 +91,7 @@ /* simple math function */ -double ll_math_acos(double x) { +double LL_math_acos(double x) { double r; LL_MATH_ERROR_RESET; r = acos(x); @@ -106,7 +99,7 @@ return r; } -double ll_math_asin(double x) { +double LL_math_asin(double x) { double r; LL_MATH_ERROR_RESET; r = asin(x); @@ -114,7 +107,7 @@ return r; } -double ll_math_atan(double x) { +double LL_math_atan(double x) { double r; LL_MATH_ERROR_RESET; r = atan(x); @@ -122,7 +115,7 @@ return r; } -double ll_math_ceil(double x) { +double LL_math_ceil(double x) { double r; LL_MATH_ERROR_RESET; r = ceil(x); @@ -130,7 +123,7 @@ return r; } -double ll_math_cos(double x) { +double LL_math_cos(double x) { double r; LL_MATH_ERROR_RESET; r = cos(x); @@ -138,7 +131,7 @@ return r; } -double ll_math_cosh(double x) { +double LL_math_cosh(double x) { double r; LL_MATH_ERROR_RESET; r = cosh(x); @@ -146,7 +139,7 @@ return r; } -double ll_math_exp(double x) { +double LL_math_exp(double x) { double r; LL_MATH_ERROR_RESET; r = exp(x); @@ -154,7 +147,7 @@ return r; } -double ll_math_fabs(double x) { +double LL_math_fabs(double x) { double r; LL_MATH_ERROR_RESET; r = fabs(x); @@ -162,7 +155,7 @@ return r; } -double ll_math_floor(double x) { +double LL_math_floor(double x) { double r; LL_MATH_ERROR_RESET; r = floor(x); @@ -170,7 +163,7 @@ return r; } -double ll_math_log(double x) { +double LL_math_log(double x) { double r; LL_MATH_ERROR_RESET; r = log(x); @@ -178,7 +171,7 @@ return r; } -double ll_math_log10(double x) { +double LL_math_log10(double x) { double r; LL_MATH_ERROR_RESET; r = log10(x); @@ -186,7 +179,7 @@ return r; } -double ll_math_sin(double x) { +double LL_math_sin(double x) { double r; LL_MATH_ERROR_RESET; r = sin(x); @@ -194,7 +187,7 @@ return r; } -double ll_math_sinh(double x) { +double LL_math_sinh(double x) { double r; LL_MATH_ERROR_RESET; r = sinh(x); @@ -202,7 +195,7 @@ return r; } -double ll_math_sqrt(double x) { +double LL_math_sqrt(double x) { double r; LL_MATH_ERROR_RESET; r = sqrt(x); @@ -210,7 +203,7 @@ return r; } -double ll_math_tan(double x) { +double LL_math_tan(double x) { double r; LL_MATH_ERROR_RESET; r = tan(x); @@ -218,7 +211,7 @@ return r; } -double ll_math_tanh(double x) { +double LL_math_tanh(double x) { double r; LL_MATH_ERROR_RESET; r = tanh(x); @@ -226,7 +219,7 @@ return r; } -struct RPyFREXP_RESULT* ll_math_frexp(double x) { +RPyFREXP_RESULT* LL_math_frexp(double x) { int expo; double m; LL_MATH_ERROR_RESET; @@ -251,7 +244,7 @@ XXX Win64 does not yet, but might when the platform matures. */ #include -double ll_time_clock(void) +double LL_time_clock(void) { static LARGE_INTEGER ctrStart; static double divisor = 0.0; @@ -283,14 +276,14 @@ #endif #endif -double ll_time_clock(void) +double LL_time_clock(void) { return ((double)clock()) / CLOCKS_PER_SEC; } #endif /* MS_WINDOWS */ -void ll_time_sleep(double secs) +void LL_time_sleep(double secs) { #if defined(MS_WINDOWS) double millisecs = secs * 1000.0; @@ -343,7 +336,7 @@ #endif /* MS_WINDOWS */ #endif /* HAVE_FTIME */ -double ll_floattime(void) +double LL_floattime(void) { /* There are three ways to get the time: (1) gettimeofday() -- resolution in microseconds @@ -378,16 +371,16 @@ } } -double ll_time_time(void) /* xxx had support for better resolutions */ +double LL_time_time(void) /* xxx had support for better resolutions */ { - return ll_floattime(); + return LL_floattime(); } -double ll_strtod_parts_to_float(struct RPyString *sign, - struct RPyString *beforept, - struct RPyString *afterpt, - struct RPyString *exponent) +double LL_strtod_parts_to_float(RPyString *sign, + RPyString *beforept, + RPyString *afterpt, + RPyString *exponent) { char *fail_pos; struct lconv *locale_data; @@ -445,7 +438,7 @@ } -struct RPyString *ll_strtod_formatd(struct RPyString *fmt, double x) { +RPyString *LL_strtod_formatd(RPyString *fmt, double x) { char buffer[120]; /* this should be enough, from PyString_Format code */ int buflen = 120; int res; @@ -512,9 +505,9 @@ /* The functions below are mapped to functions from pypy.rpython.module.* by the pypy.translator.c.extfunc.EXTERNALS dictionary. They should correspond to the functions with the suggested_primitive - flag set, and NOT necessarily directly to the ll_os_*() functions. - See for example ll_read_into(), which is called by ll_os_read(). - The latter would be messy to write here, but ll_read_into() is quite easy. + flag set, and NOT necessarily directly to the LL_os_*() functions. + See for example LL_read_into(), which is called by LL_os_read(). + The latter would be messy to write here, but LL_read_into() is quite easy. */ @@ -531,7 +524,7 @@ #endif -int ll_os_open(struct RPyString *filename, int flag, int mode) +int LL_os_open(RPyString *filename, int flag, int mode) { /* XXX unicode_file_names */ char buf[PATH_MAX]; @@ -550,7 +543,7 @@ } } -long ll_read_into(int fd, struct RPyString *buffer) +long LL_read_into(int fd, RPyString *buffer) { long n = read(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) @@ -558,7 +551,7 @@ return n; } -long ll_os_write(int fd, struct RPyString *buffer) +long LL_os_write(int fd, RPyString *buffer) { long n = write(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); if (n < 0) @@ -566,13 +559,13 @@ return n; } -void ll_os_close(int fd) +void LL_os_close(int fd) { if (close(fd) < 0) RPYTHON_RAISE_OSERROR(errno); } -int ll_os_dup(int fd) +int LL_os_dup(int fd) { fd = dup(fd); if (fd < 0) @@ -580,7 +573,7 @@ return fd; } -struct RPyString *ll_os_getcwd(void) +RPyString *LL_os_getcwd(void) { char buf[PATH_MAX]; char *res; @@ -592,7 +585,7 @@ return RPyString_FromString(buf); } -struct RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) { +RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) { long res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; res0 = (long)st.st_mode; res1 = (long)st.st_ino; /*XXX HAVE_LARGEFILE_SUPPORT!*/ @@ -610,7 +603,7 @@ } -struct RPySTAT_RESULT* ll_os_stat(struct RPyString * fname) { +RPySTAT_RESULT* LL_os_stat(RPyString * fname) { STRUCT_STAT st; int error = STAT(RPyString_AsString(fname), &st); if (error != 0) { @@ -620,7 +613,7 @@ return _stat_construct_result_helper(st); } -struct RPySTAT_RESULT* ll_os_fstat(long fd) { +RPySTAT_RESULT* LL_os_fstat(long fd) { STRUCT_STAT st; int error = FSTAT(fd, &st); if (error != 0) { @@ -630,7 +623,7 @@ return _stat_construct_result_helper(st); } -long ll_os_lseek(long fd, long pos, long how) { +long LL_os_lseek(long fd, long pos, long how) { #if defined(MS_WIN64) || defined(MS_WINDOWS) PY_LONG_LONG res; #else @@ -654,12 +647,12 @@ return res; } -long ll_os_isatty(long fd) { +long LL_os_isatty(long fd) { return (int)isatty((int)fd); } #ifdef HAVE_FTRUNCATE -void ll_os_ftruncate(long fd, long length) { /*XXX add longfile support */ +void LL_os_ftruncate(long fd, long length) { /*XXX add longfile support */ int res; res = ftruncate((int)fd, (off_t)length); if (res < 0) { @@ -668,38 +661,38 @@ } #endif -struct RPyString *ll_os_strerror(int errnum) { +RPyString *LL_os_strerror(int errnum) { char *res; res = strerror(errnum); return RPyString_FromString(res); } -long ll_os_system(struct RPyString * fname) { +long LL_os_system(RPyString * fname) { return system(RPyString_AsString(fname)); } -void ll_os_unlink(struct RPyString * fname) { +void LL_os_unlink(RPyString * fname) { int error = unlink(RPyString_AsString(fname)); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } } -void ll_os_chdir(struct RPyString * path) { +void LL_os_chdir(RPyString * path) { int error = chdir(RPyString_AsString(path)); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } } -void ll_os_mkdir(struct RPyString * path, int mode) { +void LL_os_mkdir(RPyString * path, int mode) { int error = mkdir(RPyString_AsString(path), mode); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } } -void ll_os_rmdir(struct RPyString * path) { +void LL_os_rmdir(RPyString * path) { int error = rmdir(RPyString_AsString(path)); if (error != 0) { RPYTHON_RAISE_OSERROR(errno); From ericvrp at codespeak.net Sat Aug 27 17:22:20 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 17:22:20 +0200 (CEST) Subject: [pypy-svn] r16780 - pypy/release/0.7.x/pypy/translator/llvm/test Message-ID: <20050827152220.6FC3327B80@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 17:22:19 2005 New Revision: 16780 Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py Log: skipping some tests again untill we can share genc's version Modified: pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/test/test_exc_operation.py Sat Aug 27 17:22:19 2005 @@ -73,29 +73,35 @@ ############################ def test_int_overflow(): + py.test.skip("ovf operator exception not implemented") fn = compile_function(snippet.add_func, [int]) raises(OverflowError, fn, sys.maxint) def test_int_div_ovf_zer(): + py.test.skip("ovf_zer operator exception not implemented") fn = compile_function(snippet.div_func, [int]) raises(OverflowError, fn, -1) raises(ZeroDivisionError, fn, 0) def test_int_mod_ovf_zer(): + py.test.skip("ovf_zer operator exception not implemented") fn = compile_function(snippet.mod_func, [int]) raises(OverflowError, fn, -1) raises(ZeroDivisionError, fn, 0) def test_int_rshift_val(): + py.test.skip("val operator exception not implemented") fn = compile_function(snippet.rshift_func, [int]) raises(ValueError, fn, -1) def test_int_lshift_ovf_val(): + py.test.skip("ovf_val operator exception not implemented") fn = compile_function(snippet.lshift_func, [int]) raises(ValueError, fn, -1) raises(OverflowError, fn, 1) def test_uint_arith(): + py.test.skip("zer operator exception not implemented") def fn(i): try: return ~(i*(i+1))/(i-1) @@ -107,6 +113,7 @@ assert f(i) == fn(i) def test_int_add_ovf(): + py.test.skip("ovf operator exception not implemented") def add_func(i): try: return ovfcheck(i + 1) @@ -119,6 +126,7 @@ assert f(sys.maxint) == 123 def test_int_sub_ovf(): + py.test.skip("ovf operator exception not implemented") def sub_func(i): try: return ovfcheck(i - 1) @@ -130,7 +138,8 @@ assert f(sys.maxint) == sub_func(sys.maxint) assert f(sys.maxint) == 123 -def test_shift_with_overflow(self): +def test_shift_with_overflow(): + py.test.skip("shift operator exception not implemented") shl = compile_function(llvmsnippet.shiftleft, [int, int]) shr = compile_function(llvmsnippet.shiftright, [int, int]) for i in [1, 2, 3, 100000, 2000000, sys.maxint - 1]: From ericvrp at codespeak.net Sat Aug 27 17:23:07 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 17:23:07 +0200 (CEST) Subject: [pypy-svn] r16781 - in pypy/release/0.7.x/pypy/translator/llvm: . module Message-ID: <20050827152307.0CC3C27B82@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 17:23:05 2005 New Revision: 16781 Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py pypy/release/0.7.x/pypy/translator/llvm/module/support.py Log: some cleaning up Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Sat Aug 27 17:23:05 2005 @@ -126,15 +126,12 @@ for c_name, obj in decls: if isinstance(obj, lltype.LowLevelType): - print 'XXX1', c_name self.db.prepare_type(obj) elif isinstance(obj, types.FunctionType): - print 'XXX2', c_name funcptr = getfunctionptr(self.translator, obj) c = inputconst(lltype.typeOf(funcptr), funcptr) self.db.prepare_arg_value(c) elif isinstance(lltype.typeOf(obj), lltype.Ptr): - print 'XXX3', c_name self.db.prepare_constant(lltype.typeOf(obj), obj) else: assert False, "unhandled predeclare %s %s %s" % (c_name, type(obj), obj) Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/support.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/support.py Sat Aug 27 17:23:05 2005 @@ -126,6 +126,13 @@ %cond2 = setne int %x, -2147483648 br bool %cond2, label %return_block, label %ovf ovf: +; %cond2 = setge int %x, 0 +; br bool %cond2, label %return_block, label %ovf2 +;ovf2: +; %xneg = sub int 0, %x +; %cond3 = setne int %x, %xneg +; br bool %cond3, label %return_block, label %ovf3 +;ovf3: call fastcc void %prepare_OverflowError() unwind """ From ericvrp at codespeak.net Sat Aug 27 17:23:46 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 17:23:46 +0200 (CEST) Subject: [pypy-svn] r16782 - in pypy/release/0.7.x/pypy/translator/llvm: . demo Message-ID: <20050827152346.3725A27B84@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 17:23:45 2005 New Revision: 16782 Modified: pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py pypy/release/0.7.x/pypy/translator/llvm/demo/run.py Log: fix, so run_pypy-llvm.sh actually can run the standalone Modified: pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/build_llvm_module.py Sat Aug 27 17:23:45 2005 @@ -137,4 +137,5 @@ if pyxfile: return testmodule if exe_name: - return exe_name + exe_path = str(llvmfile.dirpath().join(exe_name)) + return exe_path Modified: pypy/release/0.7.x/pypy/translator/llvm/demo/run.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/demo/run.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/demo/run.py Sat Aug 27 17:23:45 2005 @@ -18,11 +18,10 @@ f() def l(name): - compile_module(entry_point, [], standalone=True, exe_name=name) + exe_path = compile_module(entry_point, [], standalone=True, exe_name=name) print 'Running standalone (llvm-based) executable:' - cmd = "/tmp/usession-current/%s" % name - print cmd - os.system(cmd) + print exe_path + os.system(exe_path) def run(ep, name="go"): global entry_point From nik at codespeak.net Sat Aug 27 17:24:14 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 27 Aug 2005 17:24:14 +0200 (CEST) Subject: [pypy-svn] r16784 - pypy/dist/pypy/module/_sre Message-ID: <20050827152414.6CF0327B86@code1.codespeak.net> Author: nik Date: Sat Aug 27 17:24:13 2005 New Revision: 16784 Modified: pypy/dist/pypy/module/_sre/interp_sre.py Log: fixed the remaining group marking bug. Modified: pypy/dist/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/interp_sre.py Sat Aug 27 17:24:13 2005 @@ -666,7 +666,7 @@ ctx.backup_value(maxcount) ctx.backup_value(count) ctx.backup_value(repeat.last_position) # zero-width match protection - ctx.backup_value(0) + ctx.backup_value(2) # more matching ctx.repeat = repeat return False @@ -684,9 +684,6 @@ # Case 2: Resumed else: repeat = ctx.repeat - if repeat.has_matched == ctx.MATCHED: - ctx.has_matched = ctx.MATCHED - return True values = ctx.restore_values() mincount = values[0] maxcount = values[1] @@ -695,23 +692,20 @@ tail_matching = values[4] if tail_matching == 0: - if count < mincount: - ctx.has_matched = repeat.repeat_stack.pop().has_matched - if ctx.has_matched == ctx.NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - return True - if count < maxcount or maxcount == MAXREPEAT: - # XXX can we really omit this test? - #and ctx.state.string_position != repeat.last_position: - repeat.last_position = save_last_position - if repeat.repeat_stack.pop().has_matched == ctx.MATCHED: - ctx.state.marks_pop_discard() - ctx.has_matched = ctx.MATCHED - return True - ctx.state.marks_pop() + ctx.has_matched = repeat.repeat_stack.pop().has_matched + if ctx.has_matched == ctx.NOT_MATCHED: repeat.count = count - 1 ctx.state.string_position = ctx.string_position + return True + elif tail_matching == 2: + repeat.last_position = save_last_position + if repeat.repeat_stack.pop().has_matched == ctx.MATCHED: + ctx.state.marks_pop_discard() + ctx.has_matched = ctx.MATCHED + return True + ctx.state.marks_pop() + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position # Cannot match more repeated items here. Make sure the tail matches. ctx.state.repeat = repeat.previous @@ -725,7 +719,6 @@ else: # resuming after tail matching ctx.has_matched = ctx.child_context.has_matched - repeat.has_matched = ctx.has_matched if ctx.has_matched == ctx.NOT_MATCHED: ctx.state.repeat = repeat ctx.state.string_position = ctx.string_position From cfbolz at codespeak.net Sat Aug 27 17:24:14 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 17:24:14 +0200 (CEST) Subject: [pypy-svn] r16783 - pypy/extradoc/sprintinfo Message-ID: <20050827152414.9F72327B8C@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 17:24:13 2005 New Revision: 16783 Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt (props changed) Log: fixeol From rxe at codespeak.net Sat Aug 27 17:25:34 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 27 Aug 2005 17:25:34 +0200 (CEST) Subject: [pypy-svn] r16785 - pypy/release/0.7.x/lib-python/modified-2.4.1 Message-ID: <20050827152534.2EA8327B8B@code1.codespeak.net> Author: rxe Date: Sat Aug 27 17:25:33 2005 New Revision: 16785 Removed: pypy/release/0.7.x/lib-python/modified-2.4.1/linecache.py Log: performance hacks not needed anymore (see r16748) From hpk at codespeak.net Sat Aug 27 17:32:43 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 17:32:43 +0200 (CEST) Subject: [pypy-svn] r16786 - pypy/release/0.7.x/pypy/tool Message-ID: <20050827153243.6597227B90@code1.codespeak.net> Author: hpk Date: Sat Aug 27 17:32:43 2005 New Revision: 16786 Added: pypy/release/0.7.x/pypy/tool/makerelease.py (contents, props changed) Log: added a first version of the makerelease script Added: pypy/release/0.7.x/pypy/tool/makerelease.py ============================================================================== --- (empty file) +++ pypy/release/0.7.x/pypy/tool/makerelease.py Sat Aug 27 17:32:43 2005 @@ -0,0 +1,76 @@ + + +import py + +log = py.log.Producer("log") + +BASEURL = "file:///svn/pypy/release/0.7.x" +DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') + +def usage(): + print "usage: %s versionbasename" %(py.std.argv[0]) + raise SystemExit, 1 + +def cexec(cmd): + log("exec:", cmd) + return py.process.cmdexec(cmd) + +def maketargz(target): + targz = target + ".tar.gz" + basename = target.basename + old = target.dirpath().chdir() + try: + out = cexec("tar zcvf %(targz)s %(basename)s" % locals()) + finally: + old.chdir() + assert targz.check(file=1) + assert targz.size() > 0 + return targz + +def makezip(target): + tzip = target + ".zip" + if tzip.check(file=1): + log("removing", tzip) + tzip.remove() + basename = target.basename + old = target.dirpath().chdir() + try: + out = cexec("zip -r9 %(tzip)s %(basename)s" % locals()) + finally: + old.chdir() + assert tzip.check(file=1) + assert tzip.size() > 0 + return tzip + +def copydownload(fn): + log("copying to download location") + dtarget = DDIR.join(fn.basename) + fn.copy(dtarget) + return dtarget + +def forced_export(BASEURL, target, lineend="CR"): + if target.check(dir=1): + log("removing", target) + target.remove() + out = cexec("svn export --native-eol %s %s %s" + %(lineend, BASEURL, target)) + assert target.check(dir=1) + +if __name__ == '__main__': + argc = len(py.std.sys.argv) + if argc < 1: + usage() + ver = py.std.sys.argv[1] + tmpdir = py.path.local("/tmp/pypy-release") + + target = tmpdir.join(ver) + + forced_export(BASEURL, target, lineend="CR") + target_targz = maketargz(target) + assert target_targz.check(file=1) + down = copydownload(target_targz) + + forced_export(BASEURL, target, lineend="CRLF") + target_zip = makezip(target) + assert target_zip.check(file=1) + down = copydownload(target_zip) From bea at codespeak.net Sat Aug 27 17:34:57 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sat, 27 Aug 2005 17:34:57 +0200 (CEST) Subject: [pypy-svn] r16787 - pypy/extradoc/sprintinfo Message-ID: <20050827153457.1D4A127B96@code1.codespeak.net> Author: bea Date: Sat Aug 27 17:34:31 2005 New Revision: 16787 Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt Log: no Dublin ;-( Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt ============================================================================== --- pypy/extradoc/sprintinfo/dev_meth_20050827.txt (original) +++ pypy/extradoc/sprintinfo/dev_meth_20050827.txt Sat Aug 27 17:34:31 2005 @@ -1,4 +1,4 @@ -Distributed and agile development in PyPy +?Distributed and agile development in PyPy ========================================= PyPy isn't just about producing code - it's also about how we produce code. @@ -30,7 +30,7 @@ What is a sprint and why are we sprinting? -Originally the sprint methodology grew used in the Python community from +Originally the sprint methodology used in the Python community grew from practices within Zope Corporation. The definition of a sprint is "two-day or three-day focused development session, in which developers pair off together in a room and focus on building a particular subsystem". @@ -94,7 +94,7 @@ As always with methodologies you have to adapt them to fit your project (and not the other way around which is much too common). The PyPy team have been -sprinting since early 2003 and have done 12 sprints so far, 11 in Europe and 1 +sprinting since early 2003 and have done 11 sprints so far, 10 in Europe and 1 in the USA. Certain practices have proven to be more successful within this team and those are the one we are summarizing here. @@ -251,7 +251,6 @@ Amsterdam Dec 2003 Europython /Gothenburg June 2004 - Dublin Oct 2004 Vilnius Nov 2004 Leysin Jan 2005 PyCon @@ -268,7 +267,7 @@ Holger Krekel Samuele Pedronis Christian Tismer - Laura Chreighton + Laura Creighton Jacob Hall?n Michael Hudson Richard Emslie @@ -299,7 +298,9 @@ Marius Gedminas Jesus Cea Avion Olivier Dormond + Jacek Generowicz Brian Dorsey + Guido van Rossum Bob Ippolito Alan McIntyre Lutz Paelike From hpk at codespeak.net Sat Aug 27 17:36:48 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 17:36:48 +0200 (CEST) Subject: [pypy-svn] r16788 - in pypy/release/0.7.x/pypy: doc interpreter/pyparser/test interpreter/pyparser/test/samples lib/_fakecompiler lib/test2 module/posix/test module/thread/test rpython/memory rpython/memory/test rpython/test tool/pytest/test tool/pytest/test/data translator/goal translator/llvm/demo translator/llvm/test translator/tool/test Message-ID: <20050827153648.CC49627B96@code1.codespeak.net> Author: hpk Date: Sat Aug 27 17:36:46 2005 New Revision: 16788 Modified: pypy/release/0.7.x/pypy/doc/gc_planning.txt (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/samples/snippet_classes.py (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/samples/snippet_decorators.py (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/samples/snippet_docstring.py (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/samples/snippet_exceptions.py (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/samples/snippet_simple_function.py (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/samples/snippet_transformer_bug.py (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/samples/snippet_while.py (props changed) pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astcompiler.py (props changed) pypy/release/0.7.x/pypy/lib/_fakecompiler/ (props changed) pypy/release/0.7.x/pypy/lib/test2/test_deque_extra.py (props changed) pypy/release/0.7.x/pypy/module/posix/test/test_posix_libfile.py (props changed) pypy/release/0.7.x/pypy/module/thread/test/__init__.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/convertlltype.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/gc.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/gclltype.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/gcwrapper.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/lltypelayout.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/lltypesimulation.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/simulator.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/support.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/test/__init__.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/test/test_convertlltype.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/test/test_gc.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/test/test_lltypesimulation.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/test/test_simulator.py (props changed) pypy/release/0.7.x/pypy/rpython/memory/test/test_support.py (props changed) pypy/release/0.7.x/pypy/rpython/test/test_nongc.py (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/data/ (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/data/test___all__.txt (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/data/test_compile.txt (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/data/test_descr.txt (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/data/test_generators.txt (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/data/test_global.txt (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/data/test_sys.txt (props changed) pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py (props changed) pypy/release/0.7.x/pypy/translator/goal/targetcompiler.py (props changed) pypy/release/0.7.x/pypy/translator/llvm/demo/__init__.py (props changed) pypy/release/0.7.x/pypy/translator/llvm/demo/run.py (props changed) pypy/release/0.7.x/pypy/translator/llvm/test/runtest.py (props changed) pypy/release/0.7.x/pypy/translator/llvm/test/test_typed.py (props changed) pypy/release/0.7.x/pypy/translator/tool/test/__init__.py (props changed) pypy/release/0.7.x/pypy/translator/tool/test/test_cbuild.py (props changed) Log: FIXEOL From cfbolz at codespeak.net Sat Aug 27 17:37:30 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 17:37:30 +0200 (CEST) Subject: [pypy-svn] r16789 - pypy/release/0.7.x/pypy/translator/c/test Message-ID: <20050827153730.B8CFE27B9A@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 17:37:28 2005 New Revision: 16789 Modified: pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Log: added a test that tries to compile unsetenv and test whether it works Modified: pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/release/0.7.x/pypy/translator/c/test/test_extfunc.py Sat Aug 27 17:37:28 2005 @@ -477,3 +477,18 @@ res = chan.receive() assert res chan.close() + +def test_unsetenv(): + if not hasattr(os, "unsetenv"): + py.test.skip("missing unsetenv on this architecture") + def unsetenv(): + os.unsetenv("ABCDEF") + f = compile(unsetenv, []) + os.putenv("ABCDEF", "a") + cmd = '''python -c "import os, sys; sys.exit(os.getenv('ABCDEF') != 'a')"''' + assert os.system(cmd) == 0 + f() + cmd = '''python -c "import os, sys; sys.exit(os.getenv('ABCDEF') != None)"''' + assert os.system(cmd) == 0 + f() + assert os.system(cmd) == 0 From pedronis at codespeak.net Sat Aug 27 17:39:17 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 27 Aug 2005 17:39:17 +0200 (CEST) Subject: [pypy-svn] r16790 - pypy/extradoc/sprintinfo Message-ID: <20050827153917.43DFD27B9F@code1.codespeak.net> Author: pedronis Date: Sat Aug 27 17:39:15 2005 New Revision: 16790 Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt Log: fixing typos Modified: pypy/extradoc/sprintinfo/dev_meth_20050827.txt ============================================================================== --- pypy/extradoc/sprintinfo/dev_meth_20050827.txt (original) +++ pypy/extradoc/sprintinfo/dev_meth_20050827.txt Sat Aug 27 17:39:15 2005 @@ -1,4 +1,4 @@ -?Distributed and agile development in PyPy +Distributed and agile development in PyPy ========================================= PyPy isn't just about producing code - it's also about how we produce code. @@ -185,7 +185,7 @@ 4. Process - a typical PyPy sprint is 7 days with a break day in the middle. Usually sprinters show up the day before the sprint starts. The - first day has a start up meeting, with tutorials of there are participants + first day has a start up meeting, with tutorials if there are participants new to the project or if some new tool or feature have been implemented. A short presentation of the participants and their background and expectations is also good to do. Unfortunately there is always time spent @@ -265,7 +265,7 @@ Armin Rigo Holger Krekel - Samuele Pedronis + Samuele Pedroni Christian Tismer Laura Creighton Jacob Hall?n From arigo at codespeak.net Sat Aug 27 17:43:13 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 17:43:13 +0200 (CEST) Subject: [pypy-svn] r16791 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827154313.7960827BA0@code1.codespeak.net> Author: arigo Date: Sat Aug 27 17:43:12 2005 New Revision: 16791 Modified: pypy/release/0.7.x/pypy/doc/faq.txt pypy/release/0.7.x/pypy/doc/getting-started.txt Log: Describe how translate_pypy produces a 'pypy-c' executable, including in the FAQ, but warn loudly about this not being suitable for installation/redistribution. Modified: pypy/release/0.7.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/faq.txt (original) +++ pypy/release/0.7.x/pypy/doc/faq.txt Sat Aug 27 17:43:12 2005 @@ -36,4 +36,12 @@ a full and compliant Python 2.4 interpreter. RPython is only the language in which parts of PyPy itself are written. +How do I compile PyPy? + + See the `getting-started`_ guide. Note that at the moment this + produces an executable that contains a lot of things that are + hard-coded for your particular system (including paths), so it's + not really suitable for being installed or redistributed. + .. _`RPython`: coding-guide.html#rpython +.. _`getting-started`: getting-started.html Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 17:43:12 2005 @@ -421,6 +421,14 @@ 2 >>>> +With the default options, you can find the produced executable under the +name ``pypy-c``. Type ``pypy-c --help`` to see the options it supports -- +mainly the same basic options of CPython. In addition, ``pypy-c --info`` +prints the translation options that where used to produce this particular +executable. This executable contains a lot of things that are hard-coded +for your particular system (including paths), so it's not really meant to +be installed or redistributed at the moment. + If you exit the interpreter you get a pygame window with all the flowgraphs plus a pdb prompt. Moving around in the resulting flow graph is difficult because of the sheer size of the result. For this reason, the debugger prompt From ludal at codespeak.net Sat Aug 27 17:45:35 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 27 Aug 2005 17:45:35 +0200 (CEST) Subject: [pypy-svn] r16792 - pypy/release/0.7.x/pypy/interpreter/pyparser/test Message-ID: <20050827154535.E60C927BA4@code1.codespeak.net> Author: ludal Date: Sat Aug 27 17:45:34 2005 New Revision: 16792 Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astcompiler.py Log: disable compilation (not parsing) of genexp since we can't compare code objects because c-python optimizes the bytecode and we do not. The bytecode produced is still tested by some other tests (see for example lib-python/2.4.1/test/test_genexps.py Modified: pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/release/0.7.x/pypy/interpreter/pyparser/test/test_astcompiler.py Sat Aug 27 17:45:34 2005 @@ -33,7 +33,7 @@ import sys if sys.version_info[0]==2 and sys.version_info[1]>=4: # genexps and new style import don't work on python2.3 - TESTS.append(genexps) + # TESTS.append(genexps) XXX: 2.4 optimizes bytecode so our comparison doesn't work TESTS.append(imports_newstyle) # assertions give different bytecode with 2.4 (optimize if __debug__) TESTS.append(asserts) From nik at codespeak.net Sat Aug 27 17:52:45 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 27 Aug 2005 17:52:45 +0200 (CEST) Subject: [pypy-svn] r16793 - pypy/dist/pypy/module/_sre/test Message-ID: <20050827155245.F300A27BA8@code1.codespeak.net> Author: nik Date: Sat Aug 27 17:52:44 2005 New Revision: 16793 Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py Log: fixed a test which failed because of changed interface of getlower Modified: pypy/dist/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/dist/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/dist/pypy/module/_sre/test/test_interp_sre.py Sat Aug 27 17:52:44 2005 @@ -77,7 +77,7 @@ assert not isre.at_boundary(space, create_context(space, string, pos, end)) def test_getlower(space): - assert space.int_w(isre.getlower(space, space.wrap(ord("A")), space.wrap(0))) == ord("a") + assert isre.getlower(space, ord("A"), 0) == ord("a") def test_get_byte_array(space): if sys.byteorder == "big": From ludal at codespeak.net Sat Aug 27 17:57:07 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 27 Aug 2005 17:57:07 +0200 (CEST) Subject: [pypy-svn] r16795 - in pypy/release/0.7.x/lib-python: . modified-2.4.1 Message-ID: <20050827155707.B428C27BAB@code1.codespeak.net> Author: ludal Date: Sat Aug 27 17:57:05 2005 New Revision: 16795 Added: pypy/release/0.7.x/lib-python/modified-2.4.1/pprint.py - copied, changed from r16754, pypy/release/0.7.x/lib-python/2.4.1/pprint.py Modified: pypy/release/0.7.x/lib-python/conftest.py pypy/release/0.7.x/lib-python/failure_list.txt Log: - update failure_list.txt - fix the pprint module so it works with pypy (pypy returns new method objects each time we do a getattr and pprint checks for identity instead of equality to detect if we overrode one of the base objects' (dict,list,tuple) __repr__ method - move the test back to core tests since it works and pprint is widely used Modified: pypy/release/0.7.x/lib-python/conftest.py ============================================================================== --- pypy/release/0.7.x/lib-python/conftest.py (original) +++ pypy/release/0.7.x/lib-python/conftest.py Sat Aug 27 17:57:05 2005 @@ -613,7 +613,7 @@ RegrTest('test_posix.py', enabled=True), RegrTest('test_posixpath.py', enabled=True), RegrTest('test_pow.py', enabled=True, core=True), - RegrTest('test_pprint.py', enabled=True), + RegrTest('test_pprint.py', enabled=True, core=True), RegrTest('test_profile.py', enabled=True), RegrTest('test_profilehooks.py', enabled=True, core=True), RegrTest('test_pty.py', enabled=False), Modified: pypy/release/0.7.x/lib-python/failure_list.txt ============================================================================== --- pypy/release/0.7.x/lib-python/failure_list.txt (original) +++ pypy/release/0.7.x/lib-python/failure_list.txt Sat Aug 27 17:57:05 2005 @@ -1,6 +1,9 @@ test_cpickle has been re-run, still failing + ran test_cpickle on c-python using the pickle module instead of cpickle + pickle.py fails on all test_recursion but passes the test_nonrecursive + this test has a 60 level deep structure test_descr cannot easily complete this; after another quick review, the failures From nik at codespeak.net Sat Aug 27 17:59:08 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 27 Aug 2005 17:59:08 +0200 (CEST) Subject: [pypy-svn] r16796 - in pypy/release/0.7.x/pypy/module/_sre: . test Message-ID: <20050827155908.C226427BAE@code1.codespeak.net> Author: nik Date: Sat Aug 27 17:59:05 2005 New Revision: 16796 Removed: pypy/release/0.7.x/pypy/module/_sre/app_info.py Modified: pypy/release/0.7.x/pypy/module/_sre/__init__.py pypy/release/0.7.x/pypy/module/_sre/app_sre.py pypy/release/0.7.x/pypy/module/_sre/interp_sre.py pypy/release/0.7.x/pypy/module/_sre/test/test_app_sre.py pypy/release/0.7.x/pypy/module/_sre/test/test_interp_sre.py Log: merged current _sre into release branch since it now compiles! by default the pure app-level module in lib is still used right now. Modified: pypy/release/0.7.x/pypy/module/_sre/__init__.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/__init__.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/__init__.py Sat Aug 27 17:59:05 2005 @@ -9,19 +9,16 @@ """ appleveldefs = { - 'CODESIZE': 'app_info.CODESIZE', - 'MAGIC': 'app_info.MAGIC', - 'copyright': 'app_info.copyright', - 'getcodesize': 'app_info.getcodesize', 'compile': 'app_sre.compile', } interpleveldefs = { - 'getlower': 'interp_sre.getlower', + 'CODESIZE': 'space.wrap(interp_sre.CODESIZE)', + 'MAGIC': 'space.wrap(interp_sre.MAGIC)', + 'copyright': 'space.wrap(interp_sre.copyright)', + 'getlower': 'interp_sre.w_getlower', + 'getcodesize': 'interp_sre.w_getcodesize', '_State': 'interp_sre.make_state', - '_MatchContext': 'interp_sre.make_context', - '_RepeatContext': 'interp_sre.make_repeat_context', - '_match': 'interp_sre.match', - '_opcode_dispatch': 'interp_sre.opcode_dispatch', - '_opcode_is_at_interplevel': 'interp_sre.opcode_is_at_interplevel', + '_match': 'interp_sre.w_match', + '_search': 'interp_sre.w_search', } Modified: pypy/release/0.7.x/pypy/module/_sre/app_sre.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/app_sre.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/app_sre.py Sat Aug 27 17:59:05 2005 @@ -7,12 +7,8 @@ copyrighted by: Copyright (c) 1997-2001 by Secret Labs AB """ -import array, operator, sys -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 +import sys import _sre -from _sre import CODESIZE def compile(pattern, flags, code, groups=0, groupindex={}, indexgroup=[None]): @@ -47,7 +43,7 @@ instance. Return None if no position in the string matches the pattern.""" state = _sre._State(string, pos, endpos, self.flags) - if search(state, self._code): + if _sre._search(state, self._code): return SRE_Match(self, state) else: return None @@ -59,7 +55,7 @@ while state.start <= state.end: state.reset() state.string_position = state.start - if not search(state, self._code): + if not _sre._search(state, self._code): break match = SRE_Match(self, state) if self.groups == 0 or self.groups == 1: @@ -86,7 +82,7 @@ while not count or n < count: state.reset() state.string_position = state.start - if not search(state, self._code): + if not _sre._search(state, self._code): break if last_pos < state.start: sublist.append(string[last_pos:state.start]) @@ -132,7 +128,7 @@ while not maxsplit or n < maxsplit: state.reset() state.string_position = state.start - if not search(state, self._code): + if not _sre._search(state, self._code): break if state.start == state.string_position: # zero-width match if last == state.end: # or end of string @@ -185,10 +181,10 @@ return match def match(self): - return self._match_search(match) + return self._match_search(_sre._match) def search(self): - return self._match_search(search) + return self._match_search(_sre._search) class SRE_Match(object): @@ -289,324 +285,3 @@ def __deepcopy__(): raise TypeError, "cannot copy this pattern object" - - -def search(state, pattern_codes): - flags = 0 - if pattern_codes[0] == OPCODES["info"]: - # optimization info block - # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> - #if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: - # return state.fast_search(pattern_codes) - flags = pattern_codes[2] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] - - string_position = state.start - """ - if pattern_codes[0] == OPCODES["literal"]: - # Special case: Pattern starts with a literal character. This is - # used for short prefixes - character = pattern_codes[1] - while True: - while string_position < state.end \ - and ord(state.string[string_position]) != character: - string_position += 1 - if string_position >= state.end: - return False - state.start = string_position - string_position += 1 - state.string_position = string_position - if flags & SRE_INFO_LITERAL: - return True - if match(state, pattern_codes[2:]): - return True - return False - """ - - # General case - while string_position <= state.end: - state.reset() - state.start = state.string_position = string_position - if _sre._match(state, pattern_codes): - return True - string_position += 1 - return False - - -def fast_search(state, pattern_codes): - """Skips forward in a string as fast as possible using information from - an optimization info block.""" - # pattern starts with a known prefix - # <5=length> <6=skip> <7=prefix data> - flags = pattern_codes[2] - prefix_len = pattern_codes[5] - prefix_skip = pattern_codes[6] # don't really know what this is good for - prefix = pattern_codes[7:7 + prefix_len] - overlap = pattern_codes[7 + prefix_len - 1:pattern_codes[1] + 1] - pattern_codes = pattern_codes[pattern_codes[1] + 1:] - i = 0 - string_position = state.string_position - while string_position < state.end: - while True: - if ord(state.string[string_position]) != prefix[i]: - if i == 0: - break - else: - i = overlap[i] - else: - i += 1 - if i == prefix_len: - # found a potential match - state.start = string_position + 1 - prefix_len - state.string_position = string_position + 1 \ - - prefix_len + prefix_skip - if flags & SRE_INFO_LITERAL: - return True # matched all of pure literal pattern - if _sre._match(state, pattern_codes[2 * prefix_skip:]): - return True - i = overlap[i] - break - string_position += 1 - return False - -# XXX temporary constants for MatchContext.has_matched -UNDECIDED = 0 -MATCHED = 1 -NOT_MATCHED = 2 - -def match(state, pattern_codes): - # Optimization: Check string length. pattern_codes[3] contains the - # minimum length for a string to possibly match. - if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: - if state.end - state.string_position < pattern_codes[3]: - #_log("reject (got %d chars, need %d)" - # % (state.end - state.string_position, pattern_codes[3])) - return False - - dispatcher = _OpcodeDispatcher() - state.context_stack.append(_sre._MatchContext(state, pattern_codes)) - has_matched = UNDECIDED - while len(state.context_stack) > 0: - context = state.context_stack[-1] - has_matched = dispatcher.match(context) - if has_matched != UNDECIDED: # don't pop if context isn't done - state.context_stack.pop() - return has_matched == MATCHED - - -class _Dispatcher(object): - - DISPATCH_TABLE = None - - def dispatch(self, code, context): - method = self.DISPATCH_TABLE.get(code, self.__class__.unknown) - return method(self, context) - - def unknown(self, code, ctx): - raise NotImplementedError() - - def build_dispatch_table(cls, code_dict, method_prefix): - if cls.DISPATCH_TABLE is not None: - return - table = {} - for key, value in code_dict.items(): - if hasattr(cls, "%s%s" % (method_prefix, key)): - table[value] = getattr(cls, "%s%s" % (method_prefix, key)) - cls.DISPATCH_TABLE = table - - build_dispatch_table = classmethod(build_dispatch_table) - - -class _OpcodeDispatcher(_Dispatcher): - - def __init__(self): - self.executing_contexts = {} - - def match(self, context): - """Returns True if the current context matches, False if it doesn't and - None if matching is not finished, ie must be resumed after child - contexts have been matched.""" - while context.remaining_codes() > 0 and context.has_matched == UNDECIDED: - opcode = context.peek_code() - if not self.dispatch(opcode, context): - return UNDECIDED - if context.has_matched == UNDECIDED: - context.has_matched = NOT_MATCHED - return context.has_matched - - 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)] - has_finished = generator.next() - else: - if _sre._opcode_is_at_interplevel(opcode): - has_finished = _sre._opcode_dispatch(opcode, context) - else: - method = self.DISPATCH_TABLE.get(opcode, _OpcodeDispatcher.unknown) - has_finished = method(self, context) - if hasattr(has_finished, "next"): # avoid using the types module - generator = has_finished - has_finished = generator.next() - if not has_finished: - self.executing_contexts[id(context)] = generator - return has_finished - - def op_repeat(self, ctx): - # create repeat context. all the hard work is done by the UNTIL - # operator (MAX_UNTIL, MIN_UNTIL) - # <1=min> <2=max> item tail - #self._log(ctx, "REPEAT", ctx.peek_code(2), ctx.peek_code(3)) - repeat = _sre._RepeatContext(ctx) - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - child_context = ctx.push_new_context(ctx.peek_code(1) + 1) - yield False - ctx.state.repeat = repeat.previous - ctx.has_matched = child_context.has_matched - yield True - - def op_max_until(self, ctx): - # maximizing repeat - # <1=min> <2=max> item tail - repeat = ctx.state.repeat - if repeat is None: - raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") - mincount = repeat.peek_code(2) - maxcount = repeat.peek_code(3) - ctx.state.string_position = ctx.string_position - count = repeat.count + 1 - #self._log(ctx, "MAX_UNTIL", count) - - if count < mincount: - # not enough matches - repeat.count = count - child_context = repeat.push_new_context(4) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - yield True - - if (count < maxcount or maxcount == MAXREPEAT) \ - and ctx.state.string_position != repeat.last_position: - # we may have enough matches, if we can match another item, do so - repeat.count = count - ctx.state.marks_push() - save_last_position = repeat.last_position # zero-width match protection - repeat.last_position = ctx.state.string_position - child_context = repeat.push_new_context(4) - yield False - repeat.last_position = save_last_position - if child_context.has_matched == MATCHED: - ctx.state.marks_pop_discard() - ctx.has_matched = MATCHED - yield True - ctx.state.marks_pop() - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - - # cannot match more repeated items here. make sure the tail matches - ctx.state.repeat = repeat.previous - child_context = ctx.push_new_context(1) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - yield True - - def op_min_until(self, ctx): - # minimizing repeat - # <1=min> <2=max> item tail - repeat = ctx.state.repeat - if repeat is None: - raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") - mincount = repeat.peek_code(2) - maxcount = repeat.peek_code(3) - ctx.state.string_position = ctx.string_position - count = repeat.count + 1 - #self._log(ctx, "MIN_UNTIL", count) - - if count < mincount: - # not enough matches - repeat.count = count - child_context = repeat.push_new_context(4) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - yield True - - # see if the tail matches - ctx.state.marks_push() - ctx.state.repeat = repeat.previous - child_context = ctx.push_new_context(1) - yield False - if child_context.has_matched == MATCHED: - ctx.has_matched = MATCHED - yield True - ctx.state.repeat = repeat - ctx.state.string_position = ctx.string_position - ctx.state.marks_pop() - - # match more until tail matches - if count >= maxcount and maxcount != MAXREPEAT: - ctx.has_matched = NOT_MATCHED - yield True - repeat.count = count - child_context = repeat.push_new_context(4) - yield False - ctx.has_matched = child_context.has_matched - if ctx.has_matched == NOT_MATCHED: - repeat.count = count - 1 - ctx.state.string_position = ctx.string_position - yield True - - def unknown(self, ctx): - #self._log(ctx, "UNKNOWN", ctx.peek_code()) - raise RuntimeError("Internal re error. Unknown opcode: %s" % ctx.peek_code()) - - def count_repetitions(self, ctx, maxcount): - """Returns the number of repetitions of a single item, starting from the - current string position. The code pointer is expected to point to a - REPEAT_ONE operation (with the repeated 4 ahead).""" - count = 0 - real_maxcount = ctx.state.end - ctx.string_position - if maxcount < real_maxcount and maxcount != MAXREPEAT: - real_maxcount = maxcount - # XXX could special case every single character pattern here, as in C. - # This is a general solution, a bit hackisch, but works and should be - # efficient. - code_position = ctx.code_position - string_position = ctx.string_position - ctx.skip_code(4) - reset_position = ctx.code_position - while count < real_maxcount: - # this works because the single character pattern is followed by - # a success opcode - ctx.code_position = reset_position - self.dispatch(ctx.peek_code(), ctx) - if ctx.has_matched == NOT_MATCHED: # could be None as well - break - count += 1 - ctx.has_matched = UNDECIDED - ctx.code_position = code_position - ctx.string_position = string_position - return count - - def _log(self, context, opname, *args): - arg_string = ("%s " * len(args)) % args - _log("|%s|%s|%s %s" % (context.pattern_codes, - context.string_position, opname, arg_string)) - -_OpcodeDispatcher.build_dispatch_table(OPCODES, "op_") - - -def _log(message): - if 0: - print message Modified: pypy/release/0.7.x/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/interp_sre.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/interp_sre.py Sat Aug 27 17:59:05 2005 @@ -1,38 +1,57 @@ -from pypy.interpreter.baseobjspace import ObjSpace, Wrappable -# XXX is it allowed to import app-level module like this? -from pypy.module._sre.app_info import CODESIZE +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app - import sys -BIG_ENDIAN = sys.byteorder == "big" -#### Exposed functions +#### Constants and exposed functions + +# Identifying as _sre from Python 2.3 or 2.4 +MAGIC = 20031017 + +# In _sre.c this is bytesize of the code word type of the C implementation. +# There it's 2 for normal Python builds and more for wide unicode builds (large +# enough to hold a 32-bit UCS-4 encoded character). Since here in pure Python +# we only see re bytecodes as Python longs, we shouldn't have to care about the +# codesize. But sre_compile will compile some stuff differently depending on the +# codesize (e.g., charsets). +if sys.maxunicode == 65535: + CODESIZE = 2 +else: + CODESIZE = 4 + +copyright = "_sre.py 2.4 Copyright 2005 by Nik Haldimann" + +BIG_ENDIAN = sys.byteorder == "big" # XXX can we import those safely from sre_constants? +SRE_INFO_PREFIX = 1 +SRE_INFO_LITERAL = 2 SRE_FLAG_LOCALE = 4 # honour system locale SRE_FLAG_UNICODE = 32 # use unicode locale +OPCODE_INFO = 17 +OPCODE_LITERAL = 19 MAXREPEAT = 65535 -def getlower(space, w_char_ord, w_flags): - char_ord = space.int_w(w_char_ord) - flags = space.int_w(w_flags) +def w_getlower(space, w_char_ord, w_flags): + return space.wrap(getlower(space, space.int_w(w_char_ord), space.int_w(w_flags))) + +def getlower(space, char_ord, flags): if (char_ord < 128) or (flags & SRE_FLAG_UNICODE) \ or (flags & SRE_FLAG_LOCALE and char_ord < 256): w_uni_char = space.newunicode([char_ord]) w_lowered = space.call_method(w_uni_char, "lower") - return space.ord(w_lowered) + return space.int_w(space.ord(w_lowered)) else: - return space.wrap(char_ord) + return char_ord -#### Core classes +def w_getcodesize(space): + return space.wrap(CODESIZE) -# XXX the wrapped/unwrapped semantics of the following classes are currently -# very confusing because they are still used at app-level. +#### Core classes def make_state(space, w_string, w_start, w_end, w_flags): - # XXX Uhm, temporary + # XXX maybe turn this into a __new__ method of W_State return space.wrap(W_State(space, w_string, w_start, w_end, w_flags)) class W_State(Wrappable): @@ -51,14 +70,28 @@ self.end = end self.pos = start self.flags = space.int_w(w_flags) - self.reset() + self.w_reset() - def reset(self): + def w_reset(self): self.marks = [] self.lastindex = -1 self.marks_stack = [] self.context_stack = [] - self.w_repeat = self.space.w_None + self.repeat = None + + def w_create_regs(self, w_group_count): + """Creates a tuple of index pairs representing matched groups, a format + that's convenient for SRE_Match.""" + regs = [self.space.newtuple([self.space.wrap(self.start), self.space.wrap(self.string_position)])] + for group in range(self.space.int_w(w_group_count)): + mark_index = 2 * group + if mark_index + 1 < len(self.marks): + regs.append(self.space.newtuple([self.space.wrap(self.marks[mark_index]), + self.space.wrap(self.marks[mark_index + 1])])) + else: + regs.append(self.space.newtuple([self.space.wrap(-1), + self.space.wrap(-1)])) + return self.space.newtuple(regs) def set_mark(self, mark_nr, position): if mark_nr & 1: @@ -75,20 +108,6 @@ else: return -1, -1 - def create_regs(self, w_group_count): - """Creates a tuple of index pairs representing matched groups, a format - that's convenient for SRE_Match.""" - regs = [self.space.newtuple([self.space.wrap(self.start), self.space.wrap(self.string_position)])] - for group in range(self.space.int_w(w_group_count)): - mark_index = 2 * group - if mark_index + 1 < len(self.marks): - regs.append(self.space.newtuple([self.space.wrap(self.marks[mark_index]), - self.space.wrap(self.marks[mark_index + 1])])) - else: - regs.append(self.space.newtuple([self.space.wrap(-1), - self.space.wrap(-1)])) - return self.space.newtuple(regs) - def marks_push(self): self.marks_stack.append((self.marks[:], self.lastindex)) @@ -102,65 +121,48 @@ self.marks_stack.pop() def lower(self, char_ord): - return self.space.int_w(self.w_lower(self.space.wrap(char_ord))) + return getlower(self.space, char_ord, self.flags) + + # Accessors for the typedef + + def fget_start(space, self): + return space.wrap(self.start) + + def fset_start(space, self, w_value): + self.start = space.int_w(w_value) - def w_lower(self, w_char_ord): - return getlower(self.space, w_char_ord, self.space.wrap(self.flags)) + def fget_string_position(space, self): + return space.wrap(self.string_position) -def interp_attrproperty_int(name, cls): - "NOT_RPYTHON: initialization-time only" - def fget(space, obj): - return space.wrap(getattr(obj, name)) - def fset(space, obj, w_value): - setattr(obj, name, space.int_w(w_value)) - return GetSetProperty(fget, fset, cls=cls) - -def interp_attrproperty_list_w(name, cls): - "NOT_RPYTHON: initialization-time only" - def fget(space, obj): - return space.newlist(getattr(obj, name)) - return GetSetProperty(fget, cls=cls) - -def interp_attrproperty_obj_w(name, cls): - "NOT_RPYTHON: initialization-time only" - def fget(space, obj): - return getattr(obj, name) - def fset(space, obj, w_value): - setattr(obj, name, w_value) - return GetSetProperty(fget, fset, cls=cls) + def fset_string_position(space, self, w_value): + self.start = space.int_w(w_value) + +getset_start = GetSetProperty(W_State.fget_start, W_State.fset_start, cls=W_State) +getset_string_position = GetSetProperty(W_State.fget_string_position, + W_State.fset_string_position, cls=W_State) W_State.typedef = TypeDef("W_State", - string = interp_attrproperty_obj_w("w_string", W_State), - start = interp_attrproperty_int("start", W_State), - end = interp_attrproperty_int("end", W_State), - string_position = interp_attrproperty_int("string_position", W_State), + string = interp_attrproperty_w("w_string", W_State), + start = getset_start, + end = interp_attrproperty("end", W_State), + string_position = getset_string_position, pos = interp_attrproperty("pos", W_State), lastindex = interp_attrproperty("lastindex", W_State), - repeat = interp_attrproperty_obj_w("w_repeat", W_State), - reset = interp2app(W_State.reset), - create_regs = interp2app(W_State.create_regs), - marks_push = interp2app(W_State.marks_push), - marks_pop = interp2app(W_State.marks_pop), - marks_pop_keep = interp2app(W_State.marks_pop_keep), - marks_pop_discard = interp2app(W_State.marks_pop_discard), - lower = interp2app(W_State.w_lower), + reset = interp2app(W_State.w_reset), + create_regs = interp2app(W_State.w_create_regs), ) -def make_context(space, w_state, w_pattern_codes): - # XXX Uhm, temporary - return space.wrap(W_MatchContext(space, w_state, w_pattern_codes)) - -class W_MatchContext(Wrappable): +class MatchContext: UNDECIDED = 0 MATCHED = 1 NOT_MATCHED = 2 - def __init__(self, space, w_state, w_pattern_codes): + def __init__(self, space, state, pattern_codes): self.space = space - self.state = w_state - self.pattern_codes_w = space.unpackiterable(w_pattern_codes) - self.string_position = w_state.string_position + self.state = state + self.pattern_codes = pattern_codes + self.string_position = state.string_position self.code_position = 0 self.has_matched = self.UNDECIDED self.backup = [] @@ -170,12 +172,13 @@ """Creates a new child context of this context and pushes it on the stack. pattern_offset is the offset off the current code position to start interpreting from.""" - pattern_codes_w = self.pattern_codes_w[self.code_position + pattern_offset:] - w_child_context = self.space.wrap(W_MatchContext(self.space, self.state, - self.space.newlist(pattern_codes_w))) - self.state.context_stack.append(w_child_context) - self.child_context = w_child_context - return w_child_context + offset = self.code_position + pattern_offset + assert offset >= 0 + pattern_codes = self.pattern_codes[offset:] + child_context = MatchContext(self.space, self.state, pattern_codes) + self.state.context_stack.append(child_context) + self.child_context = child_context + return child_context def is_resumed(self): return self.resume_at_opcode > -1 @@ -188,42 +191,28 @@ self.backup = [] return values - def peek_char(self, w_peek=0): - # XXX temporary hack - if w_peek == 0: - w_peek = self.space.wrap(0) + def peek_char(self, peek=0): return self.space.getitem(self.state.w_string, - self.space.add(self.space.wrap(self.string_position), w_peek)) + self.space.wrap(self.string_position + peek)) def peek_char_ord(self, peek=0): - return self.space.int_w(self.space.ord(self.peek_char(self.space.wrap(peek)))) + # XXX this is not very nice + return self.space.int_w(self.space.ord(self.peek_char(peek))) def skip_char(self, skip_count): self.string_position = self.string_position + skip_count - def w_skip_char(self, w_skip_count): - self.skip_char(self.space.int_w(w_skip_count)) - def remaining_chars(self): return self.state.end - self.string_position - def w_remaining_chars(self): - return self.space.wrap(self.remaining_chars()) - def peek_code(self, peek=0): - return self.space.int_w(self.pattern_codes_w[self.code_position + peek]) - - def w_peek_code(self, w_peek=0): - return self.space.wrap(self.peek_code(self.space.int_w(w_peek))) + return self.pattern_codes[self.code_position + peek] def skip_code(self, skip_count): self.code_position = self.code_position + skip_count - def w_skip_code(self, w_skip_count): - self.skip_code(self.space.int_w(w_skip_count)) - def remaining_codes(self): - return self.space.wrap(len(self.pattern_codes_w) - self.code_position) + return len(self.pattern_codes) - self.code_position def at_beginning(self): return self.string_position == 0 @@ -231,9 +220,6 @@ def at_end(self): return self.string_position == self.state.end - def w_at_end(self): - return self.space.newbool(self.at_end()) - def at_linebreak(self): return not self.at_end() and is_linebreak(self.space, self.peek_char()) @@ -241,58 +227,114 @@ if self.at_beginning() and self.at_end(): return False that = not self.at_beginning() \ - and word_checker(self.space, self.peek_char(self.space.wrap(-1))) + and word_checker(self.space, self.peek_char(-1)) this = not self.at_end() \ and word_checker(self.space, self.peek_char()) return this != that -W_MatchContext.typedef = TypeDef("W_MatchContext", - state = interp_attrproperty_w("state", W_MatchContext), - string_position = interp_attrproperty_int("string_position", W_MatchContext), - pattern_codes = interp_attrproperty_list_w("pattern_codes_w", W_MatchContext), - code_position = interp_attrproperty_int("code_position", W_MatchContext), - has_matched = interp_attrproperty_int("has_matched", W_MatchContext), - #push_new_context = interp2app(W_MatchContext.push_new_context), - peek_char = interp2app(W_MatchContext.peek_char), - skip_char = interp2app(W_MatchContext.w_skip_char), - remaining_chars = interp2app(W_MatchContext.w_remaining_chars), - peek_code = interp2app(W_MatchContext.w_peek_code), - skip_code = interp2app(W_MatchContext.w_skip_code), - remaining_codes = interp2app(W_MatchContext.remaining_codes), - at_end = interp2app(W_MatchContext.w_at_end), -) - -def make_repeat_context(space, w_context): - # XXX Uhm, temporary - return space.wrap(W_RepeatContext(space, w_context)) -class W_RepeatContext(W_MatchContext): +class RepeatContext(MatchContext): - def __init__(self, space, w_context): - W_MatchContext.__init__(self, space, w_context.state, - space.newlist(w_context.pattern_codes_w[w_context.code_position:])) - self.w_count = space.wrap(-1) - self.w_previous = w_context.state.w_repeat - self.w_last_position = space.w_None - -W_RepeatContext.typedef = TypeDef("W_RepeatContext", W_MatchContext.typedef, - count = interp_attrproperty_obj_w("w_count", W_RepeatContext), - previous = interp_attrproperty_obj_w("w_previous", W_RepeatContext), - last_position = interp_attrproperty_obj_w("w_last_position", W_RepeatContext), -) + def __init__(self, space, context): + offset = context.code_position + assert offset >= 0 + MatchContext.__init__(self, space, context.state, + context.pattern_codes[offset:]) + self.count = -1 + self.previous = context.state.repeat + self.last_position = -1 + self.repeat_stack = [] + #### Main opcode dispatch loop -def match(space, w_state, w_pattern_codes): +def w_search(space, w_state, w_pattern_codes): + assert isinstance(w_state, W_State) + pattern_codes = [space.int_w(code) for code + in space.unpackiterable(w_pattern_codes)] + return space.newbool(search(space, w_state, pattern_codes)) + +def search(space, state, pattern_codes): + flags = 0 + if pattern_codes[0] == OPCODE_INFO: + # optimization info block + # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> + if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: + return fast_search(space, state, pattern_codes) + flags = pattern_codes[2] + offset = pattern_codes[1] + 1 + assert offset >= 0 + pattern_codes = pattern_codes[offset:] + + string_position = state.start + while string_position <= state.end: + state.w_reset() + state.start = state.string_position = string_position + if match(space, state, pattern_codes): + return True + string_position += 1 + return False + +def fast_search(space, state, pattern_codes): + """Skips forward in a string as fast as possible using information from + an optimization info block.""" + # pattern starts with a known prefix + # <5=length> <6=skip> <7=prefix data> + flags = pattern_codes[2] + prefix_len = pattern_codes[5] + assert prefix_len >= 0 + prefix_skip = pattern_codes[6] # don't really know what this is good for + assert prefix_skip >= 0 + prefix = pattern_codes[7:7 + prefix_len] + overlap_offset = 7 + prefix_len - 1 + overlap_stop = pattern_codes[1] + 1 + assert overlap_offset >= 0 + assert overlap_stop >= 0 + overlap = pattern_codes[overlap_offset:overlap_stop] + pattern_offset = pattern_codes[1] + 1 + assert pattern_offset >= 0 + pattern_codes = pattern_codes[pattern_offset:] + i = 0 + string_position = state.string_position + while string_position < state.end: + while True: + char_ord = space.int_w(space.ord( + space.getitem(state.w_string, space.wrap(string_position)))) + if char_ord != prefix[i]: + if i == 0: + break + else: + i = overlap[i] + else: + i += 1 + if i == prefix_len: + # found a potential match + state.start = string_position + 1 - prefix_len + state.string_position = string_position + 1 \ + - prefix_len + prefix_skip + if flags & SRE_INFO_LITERAL: + return True # matched all of pure literal pattern + if match(space, state, pattern_codes[2 * prefix_skip:]): + return True + i = overlap[i] + break + string_position += 1 + return False + +def w_match(space, w_state, w_pattern_codes): + assert isinstance(w_state, W_State) + pattern_codes = [space.int_w(code) for code + in space.unpackiterable(w_pattern_codes)] + return space.newbool(match(space, w_state, pattern_codes)) + +def match(space, state, pattern_codes): # Optimization: Check string length. pattern_codes[3] contains the # minimum length for a string to possibly match. - # XXX disabled for now - #if pattern_codes[0] == OPCODES["info"] and pattern_codes[3]: - # if state.end - state.string_position < pattern_codes[3]: - # return False - state = w_state - state.context_stack.append(W_MatchContext(space, state, w_pattern_codes)) - has_matched = W_MatchContext.UNDECIDED + if pattern_codes[0] == OPCODE_INFO and pattern_codes[3] > 0: + if state.end - state.string_position < pattern_codes[3]: + return False + state.context_stack.append(MatchContext(space, state, pattern_codes)) + has_matched = MatchContext.UNDECIDED while len(state.context_stack) > 0: context = state.context_stack[-1] if context.has_matched == context.UNDECIDED: @@ -301,7 +343,7 @@ has_matched = context.has_matched if has_matched != context.UNDECIDED: # don't pop if context isn't done state.context_stack.pop() - return space.newbool(has_matched == context.MATCHED) + return has_matched == MatchContext.MATCHED def dispatch_loop(space, context): """Returns MATCHED if the current context matches, NOT_MATCHED if it doesn't @@ -312,10 +354,10 @@ opcode = context.resume_at_opcode else: opcode = context.peek_code() - #try: - has_finished = opcode_dispatch_table[opcode](space, context) - #except IndexError: - # raise RuntimeError("Internal re error. Unknown opcode: %s" % opcode) + try: + has_finished = opcode_dispatch_table[opcode](space, context) + except IndexError: + raise RuntimeError("Internal re error. Unknown opcode: %s" % opcode) if not has_finished: context.resume_at_opcode = opcode return context.UNDECIDED @@ -324,19 +366,6 @@ context.has_matched = context.NOT_MATCHED return context.has_matched -def opcode_dispatch(space, w_opcode, w_context): - opcode = space.int_w(w_opcode) - if opcode >= len(opcode_dispatch_table): - return space.newbool(False) - return space.newbool(opcode_dispatch_table[opcode](space, w_context)) - -def opcode_is_at_interplevel(space, w_opcode): - opcode = space.int_w(w_opcode) - try: - return space.newbool(opcode_dispatch_table[opcode] is not None) - except IndexError: - return space.newbool(False) - def op_success(space, ctx): # end of pattern ctx.state.string_position = ctx.string_position @@ -432,7 +461,7 @@ return skip = ctx.peek_code(1) ctx.skip_code(2) # set op pointer to the set code - char_code = space.int_w(space.ord(ctx.peek_char())) + char_code = ctx.peek_char_ord() if ignore: char_code = ctx.state.lower(char_code) if not check_charset(space, char_code, ctx): @@ -587,6 +616,201 @@ ctx.has_matched = ctx.NOT_MATCHED return True +def op_repeat(space, ctx): + # create repeat context. all the hard work is done by the UNTIL + # operator (MAX_UNTIL, MIN_UNTIL) + # <1=min> <2=max> item tail + if not ctx.is_resumed(): + ctx.repeat = RepeatContext(space, ctx) + ctx.state.repeat = ctx.repeat + ctx.state.string_position = ctx.string_position + ctx.push_new_context(ctx.peek_code(1) + 1) + return False + else: + ctx.state.repeat = ctx.repeat + ctx.has_matched = ctx.child_context.has_matched + return True + +def op_max_until(space, ctx): + # maximizing repeat + # <1=min> <2=max> item tail + + # Case 1: First entry point + if not ctx.is_resumed(): + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MAX_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + if count < mincount: + # not enough matches + repeat.count = count + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(0) # Dummy for last_position + ctx.backup_value(0) + ctx.repeat = repeat + return False + if (count < maxcount or maxcount == MAXREPEAT) \ + and ctx.state.string_position != repeat.last_position: + # we may have enough matches, if we can match another item, do so + repeat.count = count + ctx.state.marks_push() + repeat.last_position = ctx.state.string_position + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(repeat.last_position) # zero-width match protection + ctx.backup_value(2) # more matching + ctx.repeat = repeat + return False + + # Cannot match more repeated items here. Make sure the tail matches. + ctx.state.repeat = repeat.previous + ctx.push_new_context(1) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(repeat.last_position) # zero-width match protection + ctx.backup_value(1) # tail matching + ctx.repeat = repeat + return False + + # Case 2: Resumed + else: + repeat = ctx.repeat + values = ctx.restore_values() + mincount = values[0] + maxcount = values[1] + count = values[2] + save_last_position = values[3] + tail_matching = values[4] + + if tail_matching == 0: + ctx.has_matched = repeat.repeat_stack.pop().has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + return True + elif tail_matching == 2: + repeat.last_position = save_last_position + if repeat.repeat_stack.pop().has_matched == ctx.MATCHED: + ctx.state.marks_pop_discard() + ctx.has_matched = ctx.MATCHED + return True + ctx.state.marks_pop() + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + + # Cannot match more repeated items here. Make sure the tail matches. + ctx.state.repeat = repeat.previous + ctx.push_new_context(1) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(repeat.last_position) # zero-width match protection + ctx.backup_value(1) # tail matching + return False + + else: # resuming after tail matching + ctx.has_matched = ctx.child_context.has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + return True + +def op_min_until(space, ctx): + # minimizing repeat + # <1=min> <2=max> item tail + + # Case 1: First entry point + if not ctx.is_resumed(): + repeat = ctx.state.repeat + if repeat is None: + raise RuntimeError("Internal re error: MIN_UNTIL without REPEAT.") + mincount = repeat.peek_code(2) + maxcount = repeat.peek_code(3) + ctx.state.string_position = ctx.string_position + count = repeat.count + 1 + + if count < mincount: + # not enough matches + repeat.count = count + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(0) + ctx.repeat = repeat + return False + + # see if the tail matches + ctx.state.marks_push() + ctx.state.repeat = repeat.previous + ctx.push_new_context(1) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(1) + ctx.repeat = repeat + return False + + # Case 2: Resumed + else: + repeat = ctx.repeat + if repeat.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + values = ctx.restore_values() + mincount = values[0] + maxcount = values[1] + count = values[2] + matching_state = values[3] + + if count < mincount: + # not enough matches + ctx.has_matched = repeat.repeat_stack.pop().has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + return True + + if matching_state == 1: + # returning from tail matching + if ctx.child_context.has_matched == ctx.MATCHED: + ctx.has_matched = ctx.MATCHED + return True + ctx.state.repeat = repeat + ctx.state.string_position = ctx.string_position + ctx.state.marks_pop() + + if not matching_state == 2: + # match more until tail matches + if count >= maxcount and maxcount != MAXREPEAT: + ctx.has_matched = ctx.NOT_MATCHED + return True + repeat.count = count + repeat.repeat_stack.append(repeat.push_new_context(4)) + ctx.backup_value(mincount) + ctx.backup_value(maxcount) + ctx.backup_value(count) + ctx.backup_value(2) + ctx.repeat = repeat + return False + + # Final return + ctx.has_matched = repeat.repeat_stack.pop().has_matched + repeat.has_matched = ctx.has_matched + if ctx.has_matched == ctx.NOT_MATCHED: + repeat.count = count - 1 + ctx.state.string_position = ctx.string_position + return True + def op_jump(space, ctx): # jump forward # / @@ -608,7 +832,7 @@ return True while group_start < group_end: # XXX This is really a bit unwieldy. Can this be improved? - new_char = space.int_w(space.ord(ctx.peek_char())) + new_char = ctx.peek_char_ord() old_char = space.int_w(space.ord( space.getitem(ctx.state.w_string, space.wrap(group_start)))) if ctx.at_end() or (not ignore and old_char != new_char) \ @@ -713,12 +937,12 @@ op_jump, op_jump, op_literal, op_literal_ignore, op_mark, - None, #MAX_UNTIL, - None, #MIN_UNTIL, + op_max_until, + op_min_until, op_not_literal, op_not_literal_ignore, None, #NEGATE, None, #RANGE, - None, #REPEAT, + op_repeat, op_repeat_one, None, #SUBPATTERN, op_min_repeat_one, @@ -824,7 +1048,7 @@ return ctx.at_beginning() def at_beginning_line(space, ctx): - return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(space.wrap(-1))) + return ctx.at_beginning() or is_linebreak(space, ctx.peek_char(-1)) def at_end(space, ctx): return ctx.at_end() or (ctx.remaining_chars() == 1 and ctx.at_linebreak()) Modified: pypy/release/0.7.x/pypy/module/_sre/test/test_app_sre.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/test/test_app_sre.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/test/test_app_sre.py Sat Aug 27 17:59:05 2005 @@ -451,6 +451,13 @@ assert re.search(r"b(? Author: nik Date: Sat Aug 27 18:01:59 2005 New Revision: 16797 Modified: pypy/release/0.7.x/pypy/interpreter/baseobjspace.py Log: tentatively enable the _sre MixedModule by default. Modified: pypy/release/0.7.x/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/baseobjspace.py (original) +++ pypy/release/0.7.x/pypy/interpreter/baseobjspace.py Sat Aug 27 18:01:59 2005 @@ -193,7 +193,7 @@ modules.append(name) modules.extend(['unicodedata', '_codecs', - 'array', 'marshal', 'errno', 'math']) + 'array', 'marshal', 'errno', 'math', '_sre']) if self.options.nofaking: modules.append('posix') From ericvrp at codespeak.net Sat Aug 27 18:43:02 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 27 Aug 2005 18:43:02 +0200 (CEST) Subject: [pypy-svn] r16799 - pypy/release/0.7.x/pypy/translator/llvm/module Message-ID: <20050827164302.0E62127B49@code1.codespeak.net> Author: ericvrp Date: Sat Aug 27 18:43:01 2005 New Revision: 16799 Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py Log: fixed typo that prevented standalone from compiling Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/support.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/support.py Sat Aug 27 18:43:01 2005 @@ -2,7 +2,6 @@ extdeclarations = """ declare ccc int %puts(sbyte*) declare ccc uint %strlen(sbyte*) -declare ccc int %strcmp(sbyte*, sbyte*) declare ccc sbyte* %memset(sbyte*, int, uint) declare ccc sbyte* %strncpy(sbyte *, sbyte *, int) """ @@ -270,7 +269,7 @@ br label %no_exit no_exit: - %indvar = phi uint [ %indvar.next, %next_arg ], [ 0, %entry ] + %indvar = phi uint [ %indvar.next, %no_exit ], [ 0, %entry ] %i.0.0 = cast uint %indvar to int %tmp.8 = getelementptr sbyte** %argv, uint %indvar %tmp.9 = load sbyte** %tmp.8 From cfbolz at codespeak.net Sat Aug 27 18:52:42 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 27 Aug 2005 18:52:42 +0200 (CEST) Subject: [pypy-svn] r16801 - pypy/release/0.7.x/pypy/rpython/module/test Message-ID: <20050827165242.A2F1127B49@code1.codespeak.net> Author: cfbolz Date: Sat Aug 27 18:52:41 2005 New Revision: 16801 Modified: pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py Log: another test that passes if you run it alone, but not if you run all the tests. Modified: pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py ============================================================================== --- pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py (original) +++ pypy/release/0.7.x/pypy/rpython/module/test/test_ll_os.py Sat Aug 27 18:52:41 2005 @@ -55,10 +55,26 @@ f.close() os.unlink(filename) +test_src = """ +import os +from pypy.tool.udir import udir +from pypy.rpython.module.ll_os import * + def test_environ(): count = 0 while 1: if not ll_os_environ(count): break count += 1 - assert count == len(os.environ.keys()) + channel.send(count == len(os.environ.keys())) +test_environ() +""" + +def test_environ(): + import py + gw = py.execnet.PopenGateway() + chan = gw.remote_exec(py.code.Source(test_src)) + res = chan.receive() + assert res + chan.close() + From rxe at codespeak.net Sat Aug 27 18:55:09 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 27 Aug 2005 18:55:09 +0200 (CEST) Subject: [pypy-svn] r16802 - in pypy/release/0.7.x/pypy/translator/llvm: . module Message-ID: <20050827165509.43D3627B49@code1.codespeak.net> Author: rxe Date: Sat Aug 27 18:55:08 2005 New Revision: 16802 Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c pypy/release/0.7.x/pypy/translator/llvm/module/support.py Log: Mission accomplished! (ericvrp/rxe) Reuse genc c code to do externs for llvm. Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Sat Aug 27 18:55:08 2005 @@ -30,16 +30,16 @@ llcode_header = ll_functions = None ll_func_names = [ - "%prepare_and_raise_IOError", - "%prepare_and_raise_ValueError", - "%prepare_and_raise_OverflowError", - "%prepare_and_raise_ZeroDivisionError", + "%raisePyExc_IOError", + "%raisePyExc_ValueError", + "%raisePyExc_OverflowError", + "%raisePyExc_ZeroDivisionError", "%RPyString_AsString", "%RPyString_FromString", "%RPyString_Size"] def get_ll(ccode, function_names): - + # goto codespeak and compile our c code request = urllib.urlencode({'ccode':ccode}) llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() @@ -66,8 +66,8 @@ returntype, s = line.split(' ', 1) funcname , s = s.split('(', 1) funcnames[funcname] = True - assert line.find("internal") == -1 - line = '%s %s %s' % ("", DEFAULT_CCONV, line,) + if line.find("internal") == -1: + line = '%s %s %s' % ("", DEFAULT_CCONV, line,) ll_lines.append(line) # patch calls to function that we just declared fastcc @@ -96,7 +96,7 @@ class GenLLVM(object): - def __init__(self, translator, debug=True): + def __init__(self, translator, debug=False): # reset counters LLVMNode.nodename_count = {} @@ -161,12 +161,26 @@ if isinstance(lltype.typeOf(obj._obj), lltype.FuncType): predeclarefn(c_name, self.db.repr_name(obj._obj)) + include_files = [] # append local file j = os.path.join - p = j(j(os.path.dirname(__file__), "module"), "genexterns.c") - ccode.append(open(p).read()) + include_files.append(j(j(os.path.dirname(__file__), "module"), "genexterns.c")) - get_ll("".join(ccode), function_names) + from pypy.translator.c import extfunc + for f in ["ll_os", "ll_math", "ll_time", "ll_strtod"]: + include_files.append(j(j(os.path.dirname(extfunc.__file__), "src"), f + ".h")) + + for f in include_files: + ccode.append(open(f).read()) + + # for debugging + ccode = "".join(ccode) + filename = udir.join("ccode.c") + f = open(str(filename), "w") + f.write(ccode) + f.close() + + get_ll(ccode, function_names) def gen_llvm_source(self, func=None): if self.debug: print 'gen_llvm_source begin) ' + time.ctime() @@ -314,8 +328,10 @@ elif entryfunc_name == 'pypy_main_noargs': #XXX just to get on with bpnn & richards extfuncnode.ExternalFuncNode.used_external_functions['%main_noargs'] = True - for f in "prepare_and_raise_OverflowError prepare_and_raise_ValueError "\ - "prepare_and_raise_ZeroDivisionError prepare_and_raise_IOError "\ + + + for f in "raisePyExc_IOError raisePyExc_ValueError "\ + "raisePyExc_OverflowError raisePyExc_ZeroDivisionError "\ "prepare_ZeroDivisionError prepare_OverflowError prepare_ValueError "\ "RPyString_FromString RPyString_AsString RPyString_Size".split(): extfuncnode.ExternalFuncNode.used_external_functions["%" + f] = True Modified: pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/genexterns.c Sat Aug 27 18:55:08 2005 @@ -1,700 +1,29 @@ +// We hand craft these in module/support.ll char *RPyString_AsString(RPyString*); int RPyString_Size(RPyString*); RPyString *RPyString_FromString(char *); +void raisePyExc_IOError(char *); +void raisePyExc_ValueError(char *); +void raisePyExc_OverflowError(char *); +void raisePyExc_ZeroDivisionError(char *); +#define RPyRaiseSimpleException(exctype, errormsg) raise##exctype(errormsg) + // Generated by rpython - argggh have to feed in prototypes RPyFREXP_RESULT *ll_frexp_result(double, int); RPyMODF_RESULT *ll_modf_result(double, double); RPySTAT_RESULT *ll_stat_result(int, int, int, int, int, int, int, int, int, int); void RPYTHON_RAISE_OSERROR(int error); -// We hand craft these in module/support.ll -void prepare_and_raise_OverflowError(char *); -void prepare_and_raise_ValueError(char *); -void prepare_and_raise_IOError(char *); - #include #include #include #include -#define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW - -int LL_math_is_error(double x) { - if (errno == ERANGE) { - if (!x) - return 0; - prepare_and_raise_OverflowError("math range error"); - } else { - prepare_and_raise_ValueError("math domain error"); - } - return 1; -} - -#define LL_MATH_ERROR_RESET errno = 0 - -#define LL_MATH_CHECK_ERROR(x, errret) do { \ - LL_MATH_SET_ERANGE_IF_MATH_ERROR(x); \ - if (errno && LL_math_is_error(x)) \ - return errret; \ -} while(0) - - -double LL_math_pow(double x, double y) { - double r; - LL_MATH_ERROR_RESET; - r = pow(x, y); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_atan2(double x, double y) { - double r; - LL_MATH_ERROR_RESET; - r = atan2(x, y); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_fmod(double x, double y) { - double r; - LL_MATH_ERROR_RESET; - r = fmod(x, y); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_ldexp(double x, long y) { - double r; - LL_MATH_ERROR_RESET; - r = ldexp(x, (int) y); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_hypot(double x, double y) { - double r; - LL_MATH_ERROR_RESET; - r = hypot(x, y); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -RPyMODF_RESULT* LL_math_modf(double x) { - double intpart, fracpart; - LL_MATH_ERROR_RESET; - fracpart = modf(x, &intpart); - LL_MATH_CHECK_ERROR(fracpart, NULL); - return ll_modf_result(fracpart, intpart); -} - -/* simple math function */ - -double LL_math_acos(double x) { - double r; - LL_MATH_ERROR_RESET; - r = acos(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_asin(double x) { - double r; - LL_MATH_ERROR_RESET; - r = asin(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_atan(double x) { - double r; - LL_MATH_ERROR_RESET; - r = atan(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_ceil(double x) { - double r; - LL_MATH_ERROR_RESET; - r = ceil(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_cos(double x) { - double r; - LL_MATH_ERROR_RESET; - r = cos(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_cosh(double x) { - double r; - LL_MATH_ERROR_RESET; - r = cosh(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_exp(double x) { - double r; - LL_MATH_ERROR_RESET; - r = exp(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_fabs(double x) { - double r; - LL_MATH_ERROR_RESET; - r = fabs(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_floor(double x) { - double r; - LL_MATH_ERROR_RESET; - r = floor(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_log(double x) { - double r; - LL_MATH_ERROR_RESET; - r = log(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_log10(double x) { - double r; - LL_MATH_ERROR_RESET; - r = log10(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_sin(double x) { - double r; - LL_MATH_ERROR_RESET; - r = sin(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_sinh(double x) { - double r; - LL_MATH_ERROR_RESET; - r = sinh(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_sqrt(double x) { - double r; - LL_MATH_ERROR_RESET; - r = sqrt(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_tan(double x) { - double r; - LL_MATH_ERROR_RESET; - r = tan(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -double LL_math_tanh(double x) { - double r; - LL_MATH_ERROR_RESET; - r = tanh(x); - LL_MATH_CHECK_ERROR(r, -1.0); - return r; -} - -RPyFREXP_RESULT* LL_math_frexp(double x) { - int expo; - double m; - LL_MATH_ERROR_RESET; - m= frexp(x, &expo); - LL_MATH_CHECK_ERROR(m, NULL); - return ll_frexp_result(m, expo); -} - -/************************************************************/ - /*** C header subsection: time module ***/ - -#include -#ifndef MS_WINDOWS -# include -#endif - - -/****** clock() ******/ - -#if defined(MS_WINDOWS) && !defined(MS_WIN64) && !defined(__BORLANDC__) -/* Win32 has better clock replacement - XXX Win64 does not yet, but might when the platform matures. */ -#include - -double LL_time_clock(void) -{ - static LARGE_INTEGER ctrStart; - static double divisor = 0.0; - LARGE_INTEGER now; - double diff; - - if (divisor == 0.0) { - LARGE_INTEGER freq; - QueryPerformanceCounter(&ctrStart); - if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { - /* Unlikely to happen - this works on all intel - machines at least! Revert to clock() */ - return clock(); - } - divisor = (double)freq.QuadPart; - } - QueryPerformanceCounter(&now); - diff = (double)(now.QuadPart - ctrStart.QuadPart); - return diff / divisor; -} - -#else /* if !MS_WINDOWS */ - -#ifndef CLOCKS_PER_SEC -#ifdef CLK_TCK -#define CLOCKS_PER_SEC CLK_TCK -#else -#define CLOCKS_PER_SEC 1000000 -#endif -#endif - -double LL_time_clock(void) -{ - return ((double)clock()) / CLOCKS_PER_SEC; -} -#endif /* MS_WINDOWS */ - - -void LL_time_sleep(double secs) -{ -#if defined(MS_WINDOWS) - double millisecs = secs * 1000.0; - unsigned long ul_millis; - - if (millisecs > (double)ULONG_MAX) { - prepare_and_raise_OverflowError("sleep length is too large"); - } - ul_millis = (unsigned long)millisecs; - /* XXX copy CPython to make this interruptible again */ - /*if (ul_millis == 0)*/ - Sleep(ul_millis); - /*else { - DWORD rc; - ResetEvent(hInterruptEvent); - rc = WaitForSingleObject(hInterruptEvent, ul_millis); - if (rc == WAIT_OBJECT_0) { - * Yield to make sure real Python signal - * handler called. - * - Sleep(1); - RPyRaiseSimpleException(PyExc_IOError, "interrupted"); - return; - } - }*/ -#else - struct timeval t; - double frac; - frac = fmod(secs, 1.0); - secs = floor(secs); - t.tv_sec = (long)secs; - t.tv_usec = (long)(frac*1000000.0); - if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) { -#ifdef EINTR - if (errno != EINTR) { -#else - if (1) { -#endif - prepare_and_raise_IOError("select() failed"); - } - } -#endif -} - - -#ifdef HAVE_FTIME -#include -#if !defined(MS_WINDOWS) && !defined(PYOS_OS2) -extern int ftime(struct timeb *); -#endif /* MS_WINDOWS */ -#endif /* HAVE_FTIME */ - -double LL_floattime(void) -{ - /* There are three ways to get the time: - (1) gettimeofday() -- resolution in microseconds - (2) ftime() -- resolution in milliseconds - (3) time() -- resolution in seconds - In all cases the return value is a float in seconds. - Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may - fail, so we fall back on ftime() or time(). - Note: clock resolution does not imply clock accuracy! */ -#ifdef HAVE_GETTIMEOFDAY - { - struct timeval t; -#ifdef GETTIMEOFDAY_NO_TZ - if (gettimeofday(&t) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; -#else /* !GETTIMEOFDAY_NO_TZ */ - if (gettimeofday(&t, (struct timezone *)NULL) == 0) - return (double)t.tv_sec + t.tv_usec*0.000001; -#endif /* !GETTIMEOFDAY_NO_TZ */ - } -#endif /* !HAVE_GETTIMEOFDAY */ - { -#if defined(HAVE_FTIME) - struct timeb t; - ftime(&t); - return (double)t.time + (double)t.millitm * (double)0.001; -#else /* !HAVE_FTIME */ - time_t secs; - time(&secs); - return (double)secs; -#endif /* !HAVE_FTIME */ - } -} - -double LL_time_time(void) /* xxx had support for better resolutions */ -{ - return LL_floattime(); -} - - -double LL_strtod_parts_to_float(RPyString *sign, - RPyString *beforept, - RPyString *afterpt, - RPyString *exponent) -{ - char *fail_pos; - struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - double x; - char *last; - int buf_size; - char *s; - char *expo = NULL; - - expo = RPyString_AsString(exponent); - - if (*expo == '\0') { - expo = "0"; - } - - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen(decimal_point); - - buf_size = RPyString_Size(sign) + - RPyString_Size(beforept) + - decimal_point_len + - RPyString_Size(afterpt) + - 1 /* e */ + - strlen(expo) + - 1 /* asciiz */ ; - - s = malloc(buf_size); - - strcpy(s, RPyString_AsString(sign)); - strcat(s, RPyString_AsString(beforept)); - strcat(s, decimal_point); - strcat(s, RPyString_AsString(afterpt)); - strcat(s, "e"); - strcat(s, expo); - - last = s + (buf_size-1); - x = strtod(s, &fail_pos); - errno = 0; - if (fail_pos > last) - fail_pos = last; - if (fail_pos == s || *fail_pos != '\0' || fail_pos != last) { - free(s); - prepare_and_raise_ValueError("invalid float literal"); - return -1.0; - } - if (x == 0.0) { /* maybe a denormal value, ask for atof behavior */ - x = strtod(s, NULL); - errno = 0; - } - free(s); - return x; -} - - -RPyString *LL_strtod_formatd(RPyString *fmt, double x) { - char buffer[120]; /* this should be enough, from PyString_Format code */ - int buflen = 120; - int res; - - res = snprintf(buffer, buflen, RPyString_AsString(fmt), x); - if (res <= 0 || res >= buflen) { - strcpy(buffer, "??.?"); /* should not occur */ - } else { - struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - char *p; - - locale_data = localeconv(); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen(decimal_point); - - if (decimal_point[0] != '.' || - decimal_point[1] != 0) - { - p = buffer; - - if (*p == '+' || *p == '-') - p++; - - while (isdigit((unsigned char)*p)) - p++; - - if (strncmp(p, decimal_point, decimal_point_len) == 0) - { - *p = '.'; - p++; - if (decimal_point_len > 1) { - int rest_len; - rest_len = strlen(p + (decimal_point_len - 1)); - memmove(p, p + (decimal_point_len - 1), - rest_len); - p[rest_len] = 0; - } - } - } - - } - - return RPyString_FromString(buffer); -} - -/************************************************************/ - /*** C header subsection: os module ***/ - -#if !(defined(MS_WIN64) || defined(MS_WINDOWS)) -# include -# include -# include -#endif - -#include -#include -#ifndef PATH_MAX - /* assume windows */ -# define PATH_MAX 254 -#endif - -/* The functions below are mapped to functions from pypy.rpython.module.* - by the pypy.translator.c.extfunc.EXTERNALS dictionary. - They should correspond to the functions with the suggested_primitive - flag set, and NOT necessarily directly to the LL_os_*() functions. - See for example LL_read_into(), which is called by LL_os_read(). - The latter would be messy to write here, but LL_read_into() is quite easy. -*/ - - -/* just do what CPython is doing... */ - -#if defined(MS_WIN64) || defined(MS_WINDOWS) -# define STAT _stati64 -# define FSTAT _fstati64 -# define STRUCT_STAT struct _stati64 -#else -# define STAT stat -# define FSTAT fstat -# define STRUCT_STAT struct stat -#endif - - -int LL_os_open(RPyString *filename, int flag, int mode) -{ - /* XXX unicode_file_names */ - char buf[PATH_MAX]; - int fd, namelen = RPyString_Size(filename); - if (namelen >= PATH_MAX) { - RPYTHON_RAISE_OSERROR(ENAMETOOLONG); - return -1; - } - else { - memcpy(buf, RPyString_AsString(filename), namelen); - buf[namelen] = 0; - fd = open(buf, flag, mode); - if (fd < 0) - RPYTHON_RAISE_OSERROR(errno); - return fd; - } -} - -long LL_read_into(int fd, RPyString *buffer) -{ - long n = read(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); - if (n < 0) - RPYTHON_RAISE_OSERROR(errno); - return n; -} - -long LL_os_write(int fd, RPyString *buffer) -{ - long n = write(fd, RPyString_AsString(buffer), RPyString_Size(buffer)); - if (n < 0) - RPYTHON_RAISE_OSERROR(errno); - return n; -} - -void LL_os_close(int fd) -{ - if (close(fd) < 0) - RPYTHON_RAISE_OSERROR(errno); -} - -int LL_os_dup(int fd) -{ - fd = dup(fd); - if (fd < 0) - RPYTHON_RAISE_OSERROR(errno); - return fd; -} - -RPyString *LL_os_getcwd(void) -{ - char buf[PATH_MAX]; - char *res; - res = getcwd(buf, sizeof buf); - if (res == NULL) { - RPYTHON_RAISE_OSERROR(errno); - return NULL; - } - return RPyString_FromString(buf); -} - -RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) { - long res0, res1, res2, res3, res4, res5, res6, res7, res8, res9; - res0 = (long)st.st_mode; - res1 = (long)st.st_ino; /*XXX HAVE_LARGEFILE_SUPPORT!*/ - res2 = (long)st.st_dev; /*XXX HAVE_LONG_LONG!*/ - res3 = (long)st.st_nlink; - res4 = (long)st.st_uid; - res5 = (long)st.st_gid; - res6 = (long)st.st_size; /*XXX HAVE_LARGEFILE_SUPPORT!*/ - res7 = (long)st.st_atime; /*XXX ignoring quite a lot of things for time here */ - res8 = (long)st.st_mtime; /*XXX ignoring quite a lot of things for time here */ - res9 = (long)st.st_ctime; /*XXX ignoring quite a lot of things for time here */ - /*XXX ignoring BLOCK info here*/ - - return ll_stat_result(res0, res1, res2, res3, res4, res5, res6, res7, res8, res9); -} - - -RPySTAT_RESULT* LL_os_stat(RPyString * fname) { - STRUCT_STAT st; - int error = STAT(RPyString_AsString(fname), &st); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - return NULL; - } - return _stat_construct_result_helper(st); -} - -RPySTAT_RESULT* LL_os_fstat(long fd) { - STRUCT_STAT st; - int error = FSTAT(fd, &st); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - return NULL; - } - return _stat_construct_result_helper(st); -} - -long LL_os_lseek(long fd, long pos, long how) { -#if defined(MS_WIN64) || defined(MS_WINDOWS) - PY_LONG_LONG res; -#else - off_t res; -#endif -#ifdef SEEK_SET - /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ - switch (how) { - case 0: how = SEEK_SET; break; - case 1: how = SEEK_CUR; break; - case 2: how = SEEK_END; break; - } -#endif /* SEEK_END */ -#if defined(MS_WIN64) || defined(MS_WINDOWS) - res = _lseeki64(fd, pos, how); -#else - res = lseek(fd, pos, how); -#endif - if (res < 0) - RPYTHON_RAISE_OSERROR(errno); - return res; -} - -long LL_os_isatty(long fd) { - return (int)isatty((int)fd); -} - -#ifdef HAVE_FTRUNCATE -void LL_os_ftruncate(long fd, long length) { /*XXX add longfile support */ - int res; - res = ftruncate((int)fd, (off_t)length); - if (res < 0) { - RPYTHON_RAISE_OSERROR(errno); - } -} -#endif - -RPyString *LL_os_strerror(int errnum) { - char *res; - res = strerror(errnum); - return RPyString_FromString(res); -} - -long LL_os_system(RPyString * fname) { - return system(RPyString_AsString(fname)); -} - -void LL_os_unlink(RPyString * fname) { - int error = unlink(RPyString_AsString(fname)); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - } -} - -void LL_os_chdir(RPyString * path) { - int error = chdir(RPyString_AsString(path)); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - } -} - -void LL_os_mkdir(RPyString * path, int mode) { - int error = mkdir(RPyString_AsString(path), mode); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - } -} +// Do this manually from python :-( +//#include "ll_os.h" +//#include "ll_math.h" +//#include "ll_time.h" +//#include "ll_strtod.h" -void LL_os_rmdir(RPyString * path) { - int error = rmdir(RPyString_AsString(path)); - if (error != 0) { - RPYTHON_RAISE_OSERROR(errno); - } -} Modified: pypy/release/0.7.x/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/module/support.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/module/support.py Sat Aug 27 18:55:08 2005 @@ -88,10 +88,11 @@ } """ % locals()) -#prepare exceptions + +#prepare and raise exceptions for exc in "IOError ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL - extfunctions["%%prepare_and_raise_%(exc)s" % locals()] = ((), """ -internal fastcc void %%prepare_and_raise_%(exc)s(sbyte* %%msg) { + extfunctions["%%raisePyExc_%(exc)s" % locals()] = ((), """ +internal fastcc void %%raisePyExc_%(exc)s(sbyte* %%msg) { ;XXX %%msg not used right now! %%exception_value = call fastcc %%RPYTHON_EXCEPTION* %%pypy_instantiate_%(exc)s() %%tmp = getelementptr %%RPYTHON_EXCEPTION* %%exception_value, int 0, uint 0 From tismer at codespeak.net Sat Aug 27 18:56:44 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 27 Aug 2005 18:56:44 +0200 (CEST) Subject: [pypy-svn] r16803 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827165644.9AF8B27B49@code1.codespeak.net> Author: tismer Date: Sat Aug 27 18:56:43 2005 New Revision: 16803 Modified: pypy/release/0.7.x/pypy/doc/README.compiling (props changed) pypy/release/0.7.x/pypy/doc/redirections (props changed) pypy/release/0.7.x/pypy/doc/style.css (props changed) Log: adjusted some eol style From arigo at codespeak.net Sat Aug 27 19:17:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 19:17:44 +0200 (CEST) Subject: [pypy-svn] r16804 - in pypy/release/0.7.x/pypy/lib: _fakecompiler _stablecompiler Message-ID: <20050827171744.CC6AA27B4B@code1.codespeak.net> Author: arigo Date: Sat Aug 27 19:17:41 2005 New Revision: 16804 Modified: pypy/release/0.7.x/pypy/lib/_fakecompiler/fakecompiler.py pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py Log: Send the tuple data to the fakecompiler.py by using repr/eval instead of marshal (which has a depth limitation). Modified: pypy/release/0.7.x/pypy/lib/_fakecompiler/fakecompiler.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_fakecompiler/fakecompiler.py (original) +++ pypy/release/0.7.x/pypy/lib/_fakecompiler/fakecompiler.py Sat Aug 27 19:17:41 2005 @@ -16,7 +16,8 @@ if __name__ == '__main__': s = file(DUMPFILE, "rb").read() - tup = marshal.loads(s) + #tup = marshal.loads(s) + tup = eval(s) tuples_or_src, filename, mode, done, flag_names = tup try: code = reallycompile(tuples_or_src, filename, mode, flag_names) Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/apphook.py Sat Aug 27 19:17:41 2005 @@ -29,7 +29,8 @@ def fakeapplevelcompile(tuples_or_src, filename, mode, flag_names): import os, marshal done = False - data = marshal.dumps( (tuples_or_src, filename, mode, done, flag_names)) + #data = marshal.dumps( (tuples_or_src, filename, mode, done, flag_names)) + data = repr( (tuples_or_src, filename, mode, done, flag_names)) f = file(DUMPFILE, "wb") f.write(data) f.close() From bea at codespeak.net Sat Aug 27 19:18:18 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sat, 27 Aug 2005 19:18:18 +0200 (CEST) Subject: [pypy-svn] r16805 - pypy/extradoc Message-ID: <20050827171818.B9E6C27B4B@code1.codespeak.net> Author: bea Date: Sat Aug 27 19:18:17 2005 New Revision: 16805 Added: pypy/extradoc/pypyorg_20050827.txt (contents, props changed) Log: first draft of content for the EU front webb page on www.pypy.org. Please check and feedback (Note that this is just the textual content - nothing in the structure is connected to design ;-) Added: pypy/extradoc/pypyorg_20050827.txt ============================================================================== --- (empty file) +++ pypy/extradoc/pypyorg_20050827.txt Sat Aug 27 19:18:17 2005 @@ -0,0 +1,126 @@ +PyPy + +Researching a higly flexible and modular language platform and implementing it by leveraging +the Open Source Python Language and Community + +The PyPy project have been an ongoing Open Source Python language implementation since 2003. +In December 2004 PyPy recieved EU-funding within the Framework Programme 6, second call for proposals +("Open development platforms and services" IST). + +A consortium of 7 partners in Germany, France and Sweden are working to achieve the goal of a +open run-time environment for the Open Source Programming Language Python. The scientific aspects of the project is +to investigate novel techniques (based on aspect-oriented programming code generation and abstract interpretation) for the implementation of +practical dynamic languages. + +A methodological goal of the project is also to show case a novel software engineering process, Sprint Driven Development. This is an Agile +methodology, providing adynamic and adaptive environment, suitable for co-operative and distributed development. + +The project is divided into three major phases, phase 1 has the focus of developing the actual research tool - the self contained compiler, +phase 2 has the focus of optimisations (core, translation and dynamic) and in phase 3 the actual integration of efforts and dissemination of the results. +The project has an expected deadline in November 2006. + +PyPy is still, though EU-funded, heavily integrated in the Open Source community of Python.The methodology of choice +is the key strategy to make sure that the community of skilled and enthusiastic developers can contribute in ways that wouldn't have been possible +without EU-funding. + +For questions regarding the PyPy-project, please email our consortium at pypy-funding at codespeak.net. + +For more detailed information, documentation and code - please visit the PyPy community housed at Codespeak +http://codespeak.net/pypy + +______________________________________________________________________________________________________________________________ + +News + +PyPy in Heidelberg August 2005 +The team met up, in total 14 people to work on the planned 0.7 release. + +PyPy sprint in Hildesheim July 2005 +The team met up at Trillke Gut and worked on the upcoming phase 1 +deliverables. The result was PyPy - selfcontained! + + +PyPy at Europython in Gothenburg June/July 2005 +The Pypy team was busy sprinting 4 days before Europython and 6 days afterwards. +There where also several PyPy talks at the conference, a joint talk by Holger Krekel, +Armin Rigo, Carl Friedrich Bolz about translation aspects of PyPy, Holger Krekel again about Py.test +and Beatrice D?ring about sprint driven development. +This sprint had 20 participants which is a PyPy record. + +PyPy at ACCU April 2005 +Armin Rigo and Jacob Hall?n held 2 talks at the ACCU conference,about PyPy and sprint driven +development. + +PyPy at PyCon in Washington March 2005 +The Pypy team sprinted at PyCon - 13 developers worked on getting +Pypy compliant with the CPython regression test. Armin Rigo and Holger Krekel +also did talks about the Object space and Py.test. + +PyPy at the Calibre conference in Paris March 2005 +Beatrice D?ring from the PyPy team participated in the Calibre workshop +"Libre software - which business model?". + +Sprint in Leysin, Switzerland January 2005 +The PyPy team met up for the first sprint after the official start of the EU funded project. +13 people participated and worked together for 7 days. +The team succeded in importing and running CPython test on PyPy. + + +Contract signed - PyPy is flying December 2004 +The PyPy team recieved contract confirmation 1 December 2004 form the Commission +The team kicked of the work with a Consortium meeting i Saarbruecken. + + +Partners + + +DFKI www.dfki.de + Stephan Busemann stephan.busemann at dfki.de + (coordinator) + + Alastair Burt alastair.burt at dfki.de + + Anders Lehmann anders.lehmann at dfki.de + +AB Strakt www.strakt.com + Jacob Hall?n jacob at strakt.com + (project manager) + + Samuele Pedroni pedronis at strakt.com + (tehnical board) + + Anders Chrigstr?m ac at strakt.com + +Change Maker www.changemaker.nu + Beatrice D?ring bea at changemaker.nu + (assistant project manager) + +Merlinux GmbH www.merlinux.de + Holger Krekel krekel at merlinux.de + (technical board) + +Heinrich Heine Universit?t D?sseldorf www.uni-duesseldorf.de/ + Armin Rigo arigo at tunes.org + (technical board) + +Tismerysoft www.stackless.com + Christian Tismer tismer at stackless.com + (technical board) + +Logilab www.logilab.fr + Nicholas Chauvat Nicolas.Chauvat at logilab.fr + + Ludovic Aubry ludal at logilab.fr + + Adrien DiMascio adim at logilab.fr + +impara GmbH www.impara.de + bert at impara.de + +Also - as individual partners: + +Laura Creighton laura at strakt.com +Eric van Riet Paap eric at vanrietpaap.nl +Richard Emslie rxe at ukshells.co.uk + + From bea at codespeak.net Sat Aug 27 19:30:48 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sat, 27 Aug 2005 19:30:48 +0200 (CEST) Subject: [pypy-svn] r16809 - pypy/extradoc/sprintinfo Message-ID: <20050827173048.3D9F527B49@code1.codespeak.net> Author: bea Date: Sat Aug 27 19:30:23 2005 New Revision: 16809 Added: pypy/extradoc/sprintinfo/template_sprintreports_20050827.txt (contents, props changed) Log: draft of template for sprint reports - we need some kind of conformity - please use as a guideline.... Feedback? Added: pypy/extradoc/sprintinfo/template_sprintreports_20050827.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/template_sprintreports_20050827.txt Sat Aug 27 19:30:23 2005 @@ -0,0 +1,35 @@ +Template for sprint reports +Author: Beatrice D?ring +Date:20050827 +Version:1.0 + +Comment: The purpose of this template is to get some kind of conformity in the +content of the sprint reports. This template in it self doesnt have to be used but please +try to follow the guidelines for content mentioned here. +------------------------------------------------------------------------------------------ + +Author: +Date: + +Sprint report: +Place, Country +Period of days + +- Short introduction about venue and local organisers. + +- Participants (name + email adress) + +- Goal of the sprint + +- Rough calendar structure of the sprint (working when, break when.., working hours etc) + +- Brief summary of work per day and who worked on what (coding, documentation etc) + +- Next sprint (when/where/who) and rough view of potential content + + + + + + + From hpk at codespeak.net Sat Aug 27 19:43:55 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 19:43:55 +0200 (CEST) Subject: [pypy-svn] r16814 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050827174355.B026F27B4B@code1.codespeak.net> Author: hpk Date: Sat Aug 27 19:43:54 2005 New Revision: 16814 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: move the resulting pypy-c with shutil to allow moves across devices Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Sat Aug 27 19:43:54 2005 @@ -659,9 +659,8 @@ print 'Generating and compiling C code...' c_entry_point = t.ccompile(standalone=standalone, gcpolicy=gcpolicy) if standalone: # xxx fragile and messy - import py - p = py.path.local(c_entry_point) - p.rename('pypy-c') + import shutil + shutil.move(c_entry_point, 'pypy-c') c_entry_point = './pypy-c' update_usession_dir() if not options['-o']: From arigo at codespeak.net Sat Aug 27 19:56:28 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 19:56:28 +0200 (CEST) Subject: [pypy-svn] r16834 - pypy/release/0.7.x/pypy/lib Message-ID: <20050827175628.0A4AB27B49@code1.codespeak.net> Author: arigo Date: Sat Aug 27 19:56:27 2005 New Revision: 16834 Removed: pypy/release/0.7.x/pypy/lib/binascii.py Log: Moved away to make room for Jacob's newer version from the trunk. From arigo at codespeak.net Sat Aug 27 19:57:22 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 19:57:22 +0200 (CEST) Subject: [pypy-svn] r16835 - pypy/release/0.7.x/pypy/lib Message-ID: <20050827175722.B7B0D27B49@code1.codespeak.net> Author: arigo Date: Sat Aug 27 19:57:22 2005 New Revision: 16835 Added: pypy/release/0.7.x/pypy/lib/binascii.py - copied unchanged from r16834, pypy/dist/pypy/lib/binascii.py Log: Moved from the trunk. From tismer at codespeak.net Sat Aug 27 20:01:59 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 27 Aug 2005 20:01:59 +0200 (CEST) Subject: [pypy-svn] r16837 - pypy/release/0.7.x/pypy/translator/llvm Message-ID: <20050827180159.5B37C27B49@code1.codespeak.net> Author: tismer Date: Sat Aug 27 20:01:57 2005 New Revision: 16837 Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Log: fix tabs Modified: pypy/release/0.7.x/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/llvm/genllvm.py (original) +++ pypy/release/0.7.x/pypy/translator/llvm/genllvm.py Sat Aug 27 20:01:57 2005 @@ -66,8 +66,8 @@ returntype, s = line.split(' ', 1) funcname , s = s.split('(', 1) funcnames[funcname] = True - if line.find("internal") == -1: - line = '%s %s %s' % ("", DEFAULT_CCONV, line,) + if line.find("internal") == -1: + line = '%s %s %s' % ("", DEFAULT_CCONV, line,) ll_lines.append(line) # patch calls to function that we just declared fastcc @@ -333,7 +333,7 @@ for f in "raisePyExc_IOError raisePyExc_ValueError "\ "raisePyExc_OverflowError raisePyExc_ZeroDivisionError "\ "prepare_ZeroDivisionError prepare_OverflowError prepare_ValueError "\ - "RPyString_FromString RPyString_AsString RPyString_Size".split(): + "RPyString_FromString RPyString_AsString RPyString_Size".split(): extfuncnode.ExternalFuncNode.used_external_functions["%" + f] = True if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() From pedronis at codespeak.net Sat Aug 27 20:04:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 27 Aug 2005 20:04:13 +0200 (CEST) Subject: [pypy-svn] r16841 - pypy/release/0.7.x/pypy/translator/c/test Message-ID: <20050827180413.9847127B49@code1.codespeak.net> Author: pedronis Date: Sat Aug 27 20:04:12 2005 New Revision: 16841 Modified: pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py Log: skip it for now Modified: pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py (original) +++ pypy/release/0.7.x/pypy/translator/c/test/test_boehm.py Sat Aug 27 20:04:12 2005 @@ -50,6 +50,7 @@ def test_boehm(): import py + py.test.skip("boehm test is fragile wrt. the number of dynamically loaded libs") from pypy.translator.tool import cbuild if not cbuild.check_boehm_presence(): py.test.skip("no boehm gc on this machine") From arigo at codespeak.net Sat Aug 27 20:04:16 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 20:04:16 +0200 (CEST) Subject: [pypy-svn] r16842 - in pypy/dist: . pypy/lib Message-ID: <20050827180416.ECF8F27B5A@code1.codespeak.net> Author: arigo Date: Sat Aug 27 20:04:15 2005 New Revision: 16842 Added: pypy/dist/ - copied from r16833, pypy/release/0.7.x/ Removed: pypy/dist/pypy/lib/binascii.py Log: Copied svn/pypy/release/0.7.x back to svn/pypy/dist. From arigo at codespeak.net Sat Aug 27 20:05:26 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 27 Aug 2005 20:05:26 +0200 (CEST) Subject: [pypy-svn] r16844 - pypy/dist/pypy/lib Message-ID: <20050827180526.E6D7A27B49@code1.codespeak.net> Author: arigo Date: Sat Aug 27 20:05:26 2005 New Revision: 16844 Added: pypy/dist/pypy/lib/binascii.py - copied unchanged from r16835, pypy/release/0.7.x/pypy/lib/binascii.py Log: This file didn't come along... From hpk at codespeak.net Sat Aug 27 20:06:45 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 20:06:45 +0200 (CEST) Subject: [pypy-svn] r16846 - pypy/release/0.7.x/pypy/tool Message-ID: <20050827180645.DA1E727B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 20:06:45 2005 New Revision: 16846 Modified: pypy/release/0.7.x/pypy/tool/makerelease.py Log: copy the resulting tar/zip files to code2 Modified: pypy/release/0.7.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.7.x/pypy/tool/makerelease.py Sat Aug 27 20:06:45 2005 @@ -44,9 +44,10 @@ def copydownload(fn): log("copying to download location") - dtarget = DDIR.join(fn.basename) - fn.copy(dtarget) - return dtarget + #fn.copy(dtarget) + ddir = DDIR + out = py.process.cmdexec("scp %(fn)s code2.codespeak.net:%(ddir)s" + % locals()) def forced_export(BASEURL, target, lineend="CR"): if target.check(dir=1): @@ -68,9 +69,9 @@ forced_export(BASEURL, target, lineend="CR") target_targz = maketargz(target) assert target_targz.check(file=1) - down = copydownload(target_targz) + copydownload(target_targz) forced_export(BASEURL, target, lineend="CRLF") target_zip = makezip(target) assert target_zip.check(file=1) - down = copydownload(target_zip) + copydownload(target_zip) From hpk at codespeak.net Sat Aug 27 20:08:29 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 20:08:29 +0200 (CEST) Subject: [pypy-svn] r16849 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827180829.7883E27B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 20:08:28 2005 New Revision: 16849 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: adjust download locations to code2 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 20:08:28 2005 @@ -21,7 +21,7 @@ *pypy-0.7* - * download one of `pypy-0.7.0.tar.bz2`_, `pypy-0.7.0.tar.gz`_ or + * download one of `pypy-0.7.0.tar.gz`_ (unix line endings) or `pypy-0.7.0.zip`_ (windows line-endings) and unpack it * alternatively run ``svn co http://codespeak.net/svn/pypy/release/0.7.0 pypy-0.7.0`` @@ -42,9 +42,9 @@ for guidance on how to continue. .. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.7.0.tar.bz2`: http://codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 -.. _`pypy-0.7.0.zip`: http://codespeak.net/download/pypy/pypy-0.7.0.zip -.. _`pypy-0.7.0.tar.gz`: http://codespeak.net/download/pypy/pypy-0.7.0.tar.gz +.. _`pypy-0.7.0.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 +.. _`pypy-0.7.0.zip`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.zip +.. _`pypy-0.7.0.tar.gz`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.gz Svn-check out & run the latest PyPy as a two-liner -------------------------------------------------- From hpk at codespeak.net Sat Aug 27 20:15:38 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 20:15:38 +0200 (CEST) Subject: [pypy-svn] r16852 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827181538.D1CF727B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 20:15:38 2005 New Revision: 16852 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: point to the beta tarballs for now Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 20:15:38 2005 @@ -21,8 +21,8 @@ *pypy-0.7* - * download one of `pypy-0.7.0.tar.gz`_ (unix line endings) or - `pypy-0.7.0.zip`_ (windows line-endings) and unpack it + * download one of `pypy-0.7.0-beta.tar.gz`_ (unix line endings) or + `pypy-0.7.0-beta.zip`_ (windows line-endings) and unpack it * alternatively run ``svn co http://codespeak.net/svn/pypy/release/0.7.0 pypy-0.7.0`` @@ -42,9 +42,11 @@ for guidance on how to continue. .. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ +.. _`pypy-0.7.0-beta.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 .. _`pypy-0.7.0.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 .. _`pypy-0.7.0.zip`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.zip -.. _`pypy-0.7.0.tar.gz`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.gz +.. _`pypy-0.7.0-beta.zip`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.zip +.. _`pypy-0.7.0-beta.tar.gz`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.tar.gz Svn-check out & run the latest PyPy as a two-liner -------------------------------------------------- From hpk at codespeak.net Sat Aug 27 20:24:30 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 20:24:30 +0200 (CEST) Subject: [pypy-svn] r16859 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827182430.C181E27B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 20:24:30 2005 New Revision: 16859 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: reformat download locations Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 20:24:30 2005 @@ -21,10 +21,14 @@ *pypy-0.7* - * download one of `pypy-0.7.0-beta.tar.gz`_ (unix line endings) or - `pypy-0.7.0-beta.zip`_ (windows line-endings) and unpack it + * download one of + + * `pypy-0.7.0-beta.tar.gz`_ (unix line endings) or + * `pypy-0.7.0-beta.zip`_ (windows line-endings) and unpack it - * alternatively run ``svn co http://codespeak.net/svn/pypy/release/0.7.0 pypy-0.7.0`` + * alternatively run + + * ``svn co http://codespeak.net/svn/pypy/release/0.7.0 pypy-0.7.0`` then change to the ``pypy-0.7.0`` directory and execute the following command line:: From hpk at codespeak.net Sat Aug 27 20:33:37 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 20:33:37 +0200 (CEST) Subject: [pypy-svn] r16860 - in pypy/release/0.7.x/pypy: doc tool Message-ID: <20050827183337.BDFA727B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 20:33:37 2005 New Revision: 16860 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt pypy/release/0.7.x/pypy/tool/makerelease.py Log: refine makerelease script link to bz2 download location Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 20:33:37 2005 @@ -23,6 +23,7 @@ * download one of + * `pypy-0.7.0-beta.tar.bz2`_ (unix line endings) or * `pypy-0.7.0-beta.tar.gz`_ (unix line endings) or * `pypy-0.7.0-beta.zip`_ (windows line-endings) and unpack it Modified: pypy/release/0.7.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.7.x/pypy/tool/makerelease.py Sat Aug 27 20:33:37 2005 @@ -3,6 +3,7 @@ import py log = py.log.Producer("log") +logexec = py.log.Producer("exec") BASEURL = "file:///svn/pypy/release/0.7.x" DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') @@ -12,7 +13,7 @@ raise SystemExit, 1 def cexec(cmd): - log("exec:", cmd) + logexec(cmd) return py.process.cmdexec(cmd) def maketargz(target): @@ -27,6 +28,18 @@ assert targz.size() > 0 return targz +def maketarbzip(target): + targz = target + ".tar.bz2" + basename = target.basename + old = target.dirpath().chdir() + try: + out = cexec("tar jcvf %(targz)s %(basename)s" % locals()) + finally: + old.chdir() + assert targz.check(file=1) + assert targz.size() > 0 + return targz + def makezip(target): tzip = target + ".zip" if tzip.check(file=1): @@ -46,8 +59,8 @@ log("copying to download location") #fn.copy(dtarget) ddir = DDIR - out = py.process.cmdexec("scp %(fn)s code2.codespeak.net:%(ddir)s" - % locals()) + out = cexec("rsync %(fn)s code2.codespeak.net:%(ddir)s" + % locals()) def forced_export(BASEURL, target, lineend="CR"): if target.check(dir=1): @@ -71,6 +84,10 @@ assert target_targz.check(file=1) copydownload(target_targz) + target_tarbzip = maketarbzip(target) + assert target_tarbzip.check(file=1) + copydownload(target_tarbzip) + forced_export(BASEURL, target, lineend="CRLF") target_zip = makezip(target) assert target_zip.check(file=1) From lac at codespeak.net Sat Aug 27 20:38:25 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 27 Aug 2005 20:38:25 +0200 (CEST) Subject: [pypy-svn] r16861 - pypy/extradoc Message-ID: <20050827183825.074F827B49@code1.codespeak.net> Author: lac Date: Sat Aug 27 20:38:23 2005 New Revision: 16861 Modified: pypy/extradoc/pypyorg_20050827.txt Log: Fix typo and my email address Modified: pypy/extradoc/pypyorg_20050827.txt ============================================================================== --- pypy/extradoc/pypyorg_20050827.txt (original) +++ pypy/extradoc/pypyorg_20050827.txt Sat Aug 27 20:38:23 2005 @@ -87,7 +87,7 @@ (project manager) Samuele Pedroni pedronis at strakt.com - (tehnical board) + (technical board) Anders Chrigstr?m ac at strakt.com @@ -119,7 +119,7 @@ Also - as individual partners: -Laura Creighton laura at strakt.com +Laura Creighton lac at strakt.com Eric van Riet Paap eric at vanrietpaap.nl Richard Emslie rxe at ukshells.co.uk From hpk at codespeak.net Sat Aug 27 20:41:35 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 20:41:35 +0200 (CEST) Subject: [pypy-svn] r16862 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827184135.7A98E27B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 20:41:35 2005 New Revision: 16862 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: fix the beta location Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 20:41:35 2005 @@ -47,7 +47,7 @@ for guidance on how to continue. .. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.7.0-beta.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 +.. _`pypy-0.7.0-beta.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.tar.bz2 .. _`pypy-0.7.0.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 .. _`pypy-0.7.0.zip`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.zip .. _`pypy-0.7.0-beta.zip`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.zip From nik at codespeak.net Sat Aug 27 20:57:44 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sat, 27 Aug 2005 20:57:44 +0200 (CEST) Subject: [pypy-svn] r16865 - pypy/release/0.7.x/pypy/module/_sre Message-ID: <20050827185744.D542027B49@code1.codespeak.net> Author: nik Date: Sat Aug 27 20:57:43 2005 New Revision: 16865 Modified: pypy/release/0.7.x/pypy/module/_sre/interp_sre.py Log: some tentative fixes to a int overflow problem Modified: pypy/release/0.7.x/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/interp_sre.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/interp_sre.py Sat Aug 27 20:57:43 2005 @@ -2,6 +2,7 @@ from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w from pypy.interpreter.gateway import interp2app +from pypy.rpython.rarithmetic import intmask import sys #### Constants and exposed functions @@ -206,6 +207,9 @@ return self.state.end - self.string_position def peek_code(self, peek=0): + return intmask(self.pattern_codes[self.code_position + peek]) + + def peek_code_uint(self, peek=0): return self.pattern_codes[self.code_position + peek] def skip_code(self, skip_count): @@ -250,7 +254,7 @@ def w_search(space, w_state, w_pattern_codes): assert isinstance(w_state, W_State) - pattern_codes = [space.int_w(code) for code + pattern_codes = [space.uint_w(code) for code in space.unpackiterable(w_pattern_codes)] return space.newbool(search(space, w_state, pattern_codes)) @@ -323,7 +327,7 @@ def w_match(space, w_state, w_pattern_codes): assert isinstance(w_state, W_State) - pattern_codes = [space.int_w(code) for code + pattern_codes = [space.uint_w(code) for code in space.unpackiterable(w_pattern_codes)] return space.newbool(match(space, w_state, pattern_codes)) @@ -1160,7 +1164,7 @@ shift = 4 else: shift = 5 - block_value = ctx.peek_code(block * (32 / CODESIZE) + block_value = ctx.peek_code_uint(block * (32 / CODESIZE) + ((char_code & 255) >> shift)) if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): return ctx.set_ok From hpk at codespeak.net Sat Aug 27 21:00:21 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 27 Aug 2005 21:00:21 +0200 (CEST) Subject: [pypy-svn] r16867 - pypy/release/0.7.x/pypy/doc Message-ID: <20050827190021.E0C3627B49@code1.codespeak.net> Author: hpk Date: Sat Aug 27 21:00:21 2005 New Revision: 16867 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: issue120 testing actually putting more focus on translation than on the previous 0.6. release focus that was still in getting-started.txt the getting-started document should be reviewed and enhanced further because it is the central hub in the release announcement (which should also be reviewed a bit) Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sat Aug 27 21:00:21 2005 @@ -37,14 +37,16 @@ python pypy/bin/py.py This will give you a PyPy prompt, i.e. a very compliant -Python interpreter implemented in Python. Because this version -of PyPy still runs on top of CPython, it runs around 2000 -times slower than the original CPython. The release focus -really was on compliancy: PyPy passes around `90% of CPythons core -language regression tests`_. - -Have a look at `interesting starting points`_ -for guidance on how to continue. +Python interpreter implemented in Python. PyPy passes +around `90% of CPythons core language regression tests`_. +Because this invocation of PyPy still runs on top of +CPython, it runs around 2000 times slower than the +original CPython. + +However, the major news with the 0.7.0 release is +that you can use PyPy to `translate itself to lower +level languages`_ after which it runs standalone +and is not dependant on CPython anymore. .. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ .. _`pypy-0.7.0-beta.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.tar.bz2 @@ -399,6 +401,8 @@ As soon as you close the PyGame window, the function is turned into C code, compiled and executed. +.. _`translate itself to lower level languages`: + translating the PyPy interpreter -------------------------------- @@ -451,7 +455,9 @@ is useful if you don't have pygame installed. * ``-llvm``: produce code for LLVM_ instead of for C. One of the biggest - things not working there is threading. + things not working there is threading. Be aware that you will + need to install llvm from CVS to successfully translate to + a LLVM target. * ``-boehm``: use the `Boehm-Demers-Weiser garbage collector`_ instead of our own reference counting implementation. From nik at codespeak.net Sun Aug 28 10:15:18 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sun, 28 Aug 2005 10:15:18 +0200 (CEST) Subject: [pypy-svn] r16921 - pypy/release/0.7.x/pypy/module/_sre Message-ID: <20050828081518.ED40427B4B@code1.codespeak.net> Author: nik Date: Sun Aug 28 10:15:18 2005 New Revision: 16921 Modified: pypy/release/0.7.x/pypy/module/_sre/interp_sre.py Log: some more intmasking required to make _sre compile Modified: pypy/release/0.7.x/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/interp_sre.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/interp_sre.py Sun Aug 28 10:15:18 2005 @@ -260,13 +260,13 @@ def search(space, state, pattern_codes): flags = 0 - if pattern_codes[0] == OPCODE_INFO: + if intmask(pattern_codes[0]) == OPCODE_INFO: # optimization info block # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> - if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: + if intmask(pattern_codes[2]) & SRE_INFO_PREFIX and intmask(pattern_codes[5]) > 1: return fast_search(space, state, pattern_codes) - flags = pattern_codes[2] - offset = pattern_codes[1] + 1 + flags = intmask(pattern_codes[2]) + offset = intmask(pattern_codes[1]) + 1 assert offset >= 0 pattern_codes = pattern_codes[offset:] @@ -284,18 +284,18 @@ an optimization info block.""" # pattern starts with a known prefix # <5=length> <6=skip> <7=prefix data> - flags = pattern_codes[2] - prefix_len = pattern_codes[5] + flags = intmask(pattern_codes[2]) + prefix_len = intmask(pattern_codes[5]) assert prefix_len >= 0 - prefix_skip = pattern_codes[6] # don't really know what this is good for + prefix_skip = intmask(pattern_codes[6]) # don't really know what this is good for assert prefix_skip >= 0 prefix = pattern_codes[7:7 + prefix_len] overlap_offset = 7 + prefix_len - 1 - overlap_stop = pattern_codes[1] + 1 + overlap_stop = intmask(pattern_codes[1]) + 1 assert overlap_offset >= 0 assert overlap_stop >= 0 overlap = pattern_codes[overlap_offset:overlap_stop] - pattern_offset = pattern_codes[1] + 1 + pattern_offset = intmask(pattern_codes[1]) + 1 assert pattern_offset >= 0 pattern_codes = pattern_codes[pattern_offset:] i = 0 @@ -304,11 +304,11 @@ while True: char_ord = space.int_w(space.ord( space.getitem(state.w_string, space.wrap(string_position)))) - if char_ord != prefix[i]: + if char_ord != intmask(prefix[i]): if i == 0: break else: - i = overlap[i] + i = intmask(overlap[i]) else: i += 1 if i == prefix_len: @@ -320,7 +320,7 @@ return True # matched all of pure literal pattern if match(space, state, pattern_codes[2 * prefix_skip:]): return True - i = overlap[i] + i = intmask(overlap[i]) break string_position += 1 return False @@ -334,8 +334,8 @@ def match(space, state, pattern_codes): # Optimization: Check string length. pattern_codes[3] contains the # minimum length for a string to possibly match. - if pattern_codes[0] == OPCODE_INFO and pattern_codes[3] > 0: - if state.end - state.string_position < pattern_codes[3]: + if intmask(pattern_codes[0]) == OPCODE_INFO and intmask(pattern_codes[3]) > 0: + if state.end - state.string_position < intmask(pattern_codes[3]): return False state.context_stack.append(MatchContext(space, state, pattern_codes)) has_matched = MatchContext.UNDECIDED From hpk at codespeak.net Sun Aug 28 10:25:41 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 10:25:41 +0200 (CEST) Subject: [pypy-svn] r16922 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828082541.6640127B4B@code1.codespeak.net> Author: hpk Date: Sun Aug 28 10:25:40 2005 New Revision: 16922 Modified: pypy/release/0.7.x/pypy/doc/architecture.txt Log: updates to the status-of-the-implementation chapter architecture document, also moved the chapter to the end and i guess at some point it should become its own document. Modified: pypy/release/0.7.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.7.x/pypy/doc/architecture.txt Sun Aug 28 10:25:40 2005 @@ -53,33 +53,6 @@ .. _Psyco: http://psyco.sourceforge.net .. _Stackless: http://stackless.com -Status of the implementation (Aug 2005) ---------------------------------------- - -In a number of one week sprints, attracting approximately 10 developers each, -we made an almost complete implementation of Python in Python. - -Our rather complete and Python 2.4-compliant interpreter is about 30'000-50'000 -lines of code (depending on the way you count code borrowed and adapted from -other sources), with another 14'000 lines of unit tests. -If we include the tools, the parts related to code analysis and generation, -and the standard library modules ported from C, PyPy is now 105'000 lines of -code and 29'000 lines of tests. - -PyPy already passes a lot of CPython's own regression tests, including -`90% of the core tests`_ -not depending on C extension modules (most of the remaining 10% are -arguably dependant on very obscure implementation details of CPython). - -The PyPy code base can be translated to a static executable. This is done -by generating either C or LLVM_ code, using the Boehm garbage collector or -(for C) reference counting. The result is around `300 times slower`_ than -CPython (this figure can vary quite a bit). - -.. _`90% of the core tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`300 times slower`: faq.html#whysoslow - - Higher level picture ==================== @@ -88,6 +61,8 @@ remains rather simple and unchanged. There are two independent basic subsystems: `the Standard Interpreter`_ and `the Translation Process`_. +.. _`standard interpreter`: + The Standard Interpreter ------------------------ @@ -398,6 +373,41 @@ `translation document`_. There is a graph_ that gives an overview over the whole process. +Status of the implementation (Aug 2005) +========================================== + +With the pypy-0.7.0 release we have a static self-contained +translation of our `standard interpreter`_. It is `very compliant`_ +to CPython 2.4.1 but you can still not run too many existing +programs on it because we are missing a number of C-modules +like socket or support for process creation. The self-contained +PyPy version runs around `300 times slower`_ than CPython but +this figure can vary quite a bit as we still haven't focused +on profiling and optimizing bottlenecks at all. + +Also, we still are undergoing efforts to get a fast and stable +Python compiler on top of our existing nicely working Parser. +It turned out we cannot fully build on the existing compiler +package in CPython's standard library because it is not +written in a style that allows translation and also it is not +implementing all of the features CPython's c-level compiler. +We thus have to run the compiler at application-level which +contributes a lot to the perceived slowness of the interactive +command line. + +Our rather complete and Python 2.4-compliant interpreter consists +of about 30'000-50'000 lines of code (depending on the way you +count code borrowed and adapted from other sources), with +another 14'000 lines of unit tests. If we include the tools, +the parts related to code analysis and generation, and the +standard library modules ported from C, PyPy is now 105'000 +lines of code and 29'000 lines of tests. Refer to +the `statistics web page`_ for more detailed information. + +.. _`statistics web page`: http://codespeak.net/~hpk/pypy-stat/ +.. _`very compliant`: http://codespeak.net/~hpk/pypy-testresult/ +.. _`300 times slower`: faq.html#whysoslow + .. _`RPython`: coding-guide.html#rpython .. _`abstract interpretation`: theory.html#abstract-interpretation .. _`translation document`: translation.html From hpk at codespeak.net Sun Aug 28 10:26:17 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 10:26:17 +0200 (CEST) Subject: [pypy-svn] r16923 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828082617.1097B27B4B@code1.codespeak.net> Author: hpk Date: Sun Aug 28 10:26:16 2005 New Revision: 16923 Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Log: medium size refactoring of the 0.7.0 release announcement Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/release-0.7.0.txt (original) +++ pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Sun Aug 28 10:26:16 2005 @@ -1,34 +1,46 @@ -PyPy-0.7.0: first self-contained Python Implementation +pypy-0.7.0: first self-contained Python Implementation ============================================================== -The PyPy Development Team is happy to announce its first -public release of a fully translatable self contained Python -implementation. The 0.7 release is a preview release showcasing the -results of our efforts in the last few months: +What was once just an idea between a few people discussing +on some nested mailing list thread and in a pub became reality ... +the PyPy development team is happy to announce its first +public release of a fully translatable self contained Python +implementation. The 0.7 release showcases the results of our +efforts in the last few months since the 0.6 preview releae +which have been partially funded by the European Union: + +- whole program type inference on our Python Interpreter + implementation with full translation to two different + machine-level targets: C and LLVM -- full program type inference with full translation - to two different machine-level targets: C and LLVM +- a translation choice of using a refcounting or Boehm + garbage collectors -- the ability to translate with thread support or without +- the ability to translate with or without thread support -- a translation choice of using a reference counting or Boehm - garbage collector +- very complete language-level compliancy with CPython 2.4.1 -- very high compliancy with Python 2.4.1 (fully based on - new style classes) What is PyPy (about)? ------------------------------------------------ -PyPy is an MIT-licensed reimplementation of Python written in Python -itself, flexible and easy to experiment with. It translates itself -to lower level languages. Our long-term goals are to 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 to become aspects of the translation process - as opposed to -encoding low level details into a language implementation itself. -Eventually, dynamic optimization techniques - implemented as another -translation aspect - should become robust against language changes. +PyPy is an MIT-licensed research-oriented reimplementation of +Python written in Python itself, flexible and easy to +experiment with. It translates itself to lower level +languages. Our goals are to target a large variety of +platforms, small and large, by providing a compilation toolsuite +that can produce custom Python versions. Platform, Memory and +Threading models are to become aspects of the translation +process - as opposed to encoding low level details into a +language implementation itself. Eventually, dynamic +optimization techniques - implemented as another translation +aspect - should become robust against language changes. + +Note that PyPy is mainly a research and development project +and does not by itself focus on getting a production-ready +Python implementation although we do hope and expect it to +become a viable contender in that area sometime next year. + Where to start? ----------------------------- @@ -39,15 +51,23 @@ PyPy Homepage: http://codespeak.net/pypy/ -The interpreter and object model implementations shipped with 0.7 can -run on their own and implement the core language features of -Python as of CPython 2.4. However, we do not recommend using -PyPy for anything else than for playing or research purposes. +The interpreter and object model implementations shipped with +the 0.7 version can run on their own and implement the core +language features of Python as of CPython 2.4. However, we still +do not recommend using PyPy for anything else than for education, +playing or research purposes. Ongoing work and near term goals --------------------------------- -XXX +PyPy has been developed during approximately 15 coding sprints +across Europe and the US. It continues to be a very +dynamically and incrementally evolving project with many +one-week meetings to follow. You are invited to consider coming to +the next such meeting in Paris mid October 2005 where we intend to +plan and head for an even more intense phase of the project +involving building a JIT-Compiler and enabling unique +features not found in other Python language implementations. PyPy has been a community effort from the start and it would not have got that far without the coding and feedback support @@ -60,18 +80,25 @@ have fun, - the pypy-dev team ... - - (insert names here) - + the pypy team, of which here is a partial snapshot + of mainly involved persons: + Armin Rigo, Samuele Pedroni, + Holger Krekel, Christian Tismer, + Carl Friedrich Bolz, Michael Hudson, + Erik van Riet Paap, Richard Emslie, + Anders Chrigstroem, Anders Lehmann, + Ludovic Aubry, Adrien Di Mascio, + Niklaus Haldimann, Jacob Hallen, + Bea During, Laura Creighton, + and many contributors ... PyPy development and activities happen as an open source project -and with the support of a consortium funded by a two year EU IST -research grant. Here is a list of partners of the EU project: +and with the support of a consortium partially funded by a two +year European Union IST research grant. Here is a list of +the full partners of that consortium: Heinrich-Heine University (Germany), AB Strakt (Sweden) merlinux GmbH (Germany), tismerysoft GmbH(Germany) Logilab Paris (France), DFKI GmbH (Germany) - ChangeMaker (Sweden) - + ChangeMaker (Sweden), Impara (Germany) From ale at codespeak.net Sun Aug 28 10:27:39 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 28 Aug 2005 10:27:39 +0200 (CEST) Subject: [pypy-svn] r16924 - pypy/release/0.7.x/pypy/module/_codecs Message-ID: <20050828082739.6FD6A27B4B@code1.codespeak.net> Author: ale Date: Sun Aug 28 10:27:38 2005 New Revision: 16924 Modified: pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py Log: Fixing a couple of bugs in unicode-escape encode of named unicode chars A unsafe check of end of string Forgot to raise exceptions if the encoding from succeeding Modified: pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py (original) +++ pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py Sun Aug 28 10:27:38 2005 @@ -1480,15 +1480,15 @@ elif ch == 'N': message = "malformed \\N character escape" #pos += 1 + look = pos try: import unicodedata except ImportError: message = "\\N escapes not supported (can't load unicodedata module)" unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,size) - if (s[pos] == '{'): - look = pos+1 + if (s[look] == '{'): #/* look for the closing brace */ - while (s[look] != '}' and look < size): + while (look < size and s[look] != '}'): look += 1 if (look > pos+1 and look < size and s[look] == '}'): #/* found a name. look it up in the unicode database */ @@ -1503,6 +1503,10 @@ x = hexescape(s,pos+1,look-pos,message,errors) p += x[0] pos = x[1] + else: + x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look) + else: + x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look) else: if (pos > size): message = "\\ at end of string" From pedronis at codespeak.net Sun Aug 28 10:49:16 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 10:49:16 +0200 (CEST) Subject: [pypy-svn] r16934 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20050828084916.CAEEC27B4B@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 10:49:15 2005 New Revision: 16934 Modified: pypy/dist/pypy/objspace/std/longobject.py pypy/dist/pypy/objspace/std/test/test_longobject.py Log: try to mimic better CPython behavior with math.log(negative long or zero long) Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Sun Aug 28 10:49:15 2005 @@ -1293,6 +1293,8 @@ small enough to fit in an IEEE single. log and log10 are even smaller. """ x, e = _AsScaledDouble(w_arg); + if x <= 0.0: + raise ValueError # Value is ~= x * 2**(e*SHIFT), so the log ~= # log(x) + log(2) * e * SHIFT. # CAUTION: e*SHIFT may overflow using int arithmetic, Modified: pypy/dist/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_longobject.py Sun Aug 28 10:49:15 2005 @@ -395,3 +395,13 @@ assert hash(123456789L) == 123456789 assert hash(1234567890123456789L) == -1895067127 assert hash(-3**333) == -368329968 + + def math_log(self): + import math + raises(ValueError, math.log, 0L) + raises(ValueError, math.log, -1L) + raises(ValueError, math.log, -2L) + raises(ValueError, math.log, -(1L << 10000)) + raises(ValueError, math.log, 0) + raises(ValueError, math.log, -1) + raises(ValueError, math.log, -2) From pedronis at codespeak.net Sun Aug 28 10:51:49 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 10:51:49 +0200 (CEST) Subject: [pypy-svn] r16936 - in pypy/release/0.7.x/pypy/objspace/std: . test Message-ID: <20050828085149.3E04C27B4B@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 10:51:47 2005 New Revision: 16936 Modified: pypy/release/0.7.x/pypy/objspace/std/longobject.py pypy/release/0.7.x/pypy/objspace/std/test/test_longobject.py Log: fix for math.log(long) should have been checked in the release branch in the first place (oops) Modified: pypy/release/0.7.x/pypy/objspace/std/longobject.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/std/longobject.py (original) +++ pypy/release/0.7.x/pypy/objspace/std/longobject.py Sun Aug 28 10:51:47 2005 @@ -1293,6 +1293,8 @@ small enough to fit in an IEEE single. log and log10 are even smaller. """ x, e = _AsScaledDouble(w_arg); + if x <= 0.0: + raise ValueError # Value is ~= x * 2**(e*SHIFT), so the log ~= # log(x) + log(2) * e * SHIFT. # CAUTION: e*SHIFT may overflow using int arithmetic, Modified: pypy/release/0.7.x/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/release/0.7.x/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/release/0.7.x/pypy/objspace/std/test/test_longobject.py Sun Aug 28 10:51:47 2005 @@ -395,3 +395,13 @@ assert hash(123456789L) == 123456789 assert hash(1234567890123456789L) == -1895067127 assert hash(-3**333) == -368329968 + + def math_log(self): + import math + raises(ValueError, math.log, 0L) + raises(ValueError, math.log, -1L) + raises(ValueError, math.log, -2L) + raises(ValueError, math.log, -(1L << 10000)) + raises(ValueError, math.log, 0) + raises(ValueError, math.log, -1) + raises(ValueError, math.log, -2) From nik at codespeak.net Sun Aug 28 10:54:53 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sun, 28 Aug 2005 10:54:53 +0200 (CEST) Subject: [pypy-svn] r16938 - pypy/release/0.7.x/pypy/module/_sre Message-ID: <20050828085453.C571927B4B@code1.codespeak.net> Author: nik Date: Sun Aug 28 10:54:52 2005 New Revision: 16938 Modified: pypy/release/0.7.x/pypy/module/_sre/interp_sre.py Log: converting regex bytecodes to integers before interpretation, even if they're longs Modified: pypy/release/0.7.x/pypy/module/_sre/interp_sre.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/interp_sre.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/interp_sre.py Sun Aug 28 10:54:52 2005 @@ -207,9 +207,6 @@ return self.state.end - self.string_position def peek_code(self, peek=0): - return intmask(self.pattern_codes[self.code_position + peek]) - - def peek_code_uint(self, peek=0): return self.pattern_codes[self.code_position + peek] def skip_code(self, skip_count): @@ -254,19 +251,19 @@ def w_search(space, w_state, w_pattern_codes): assert isinstance(w_state, W_State) - pattern_codes = [space.uint_w(code) for code + pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] return space.newbool(search(space, w_state, pattern_codes)) def search(space, state, pattern_codes): flags = 0 - if intmask(pattern_codes[0]) == OPCODE_INFO: + if pattern_codes[0] == OPCODE_INFO: # optimization info block # <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> - if intmask(pattern_codes[2]) & SRE_INFO_PREFIX and intmask(pattern_codes[5]) > 1: + if pattern_codes[2] & SRE_INFO_PREFIX and pattern_codes[5] > 1: return fast_search(space, state, pattern_codes) - flags = intmask(pattern_codes[2]) - offset = intmask(pattern_codes[1]) + 1 + flags = pattern_codes[2] + offset = pattern_codes[1] + 1 assert offset >= 0 pattern_codes = pattern_codes[offset:] @@ -284,18 +281,18 @@ an optimization info block.""" # pattern starts with a known prefix # <5=length> <6=skip> <7=prefix data> - flags = intmask(pattern_codes[2]) - prefix_len = intmask(pattern_codes[5]) + flags = pattern_codes[2] + prefix_len = pattern_codes[5] assert prefix_len >= 0 - prefix_skip = intmask(pattern_codes[6]) # don't really know what this is good for + prefix_skip = pattern_codes[6] # don't really know what this is good for assert prefix_skip >= 0 prefix = pattern_codes[7:7 + prefix_len] overlap_offset = 7 + prefix_len - 1 - overlap_stop = intmask(pattern_codes[1]) + 1 + overlap_stop = pattern_codes[1] + 1 assert overlap_offset >= 0 assert overlap_stop >= 0 overlap = pattern_codes[overlap_offset:overlap_stop] - pattern_offset = intmask(pattern_codes[1]) + 1 + pattern_offset = pattern_codes[1] + 1 assert pattern_offset >= 0 pattern_codes = pattern_codes[pattern_offset:] i = 0 @@ -304,11 +301,11 @@ while True: char_ord = space.int_w(space.ord( space.getitem(state.w_string, space.wrap(string_position)))) - if char_ord != intmask(prefix[i]): + if char_ord != prefix[i]: if i == 0: break else: - i = intmask(overlap[i]) + i = overlap[i] else: i += 1 if i == prefix_len: @@ -320,22 +317,22 @@ return True # matched all of pure literal pattern if match(space, state, pattern_codes[2 * prefix_skip:]): return True - i = intmask(overlap[i]) + i = overlap[i] break string_position += 1 return False def w_match(space, w_state, w_pattern_codes): assert isinstance(w_state, W_State) - pattern_codes = [space.uint_w(code) for code + pattern_codes = [intmask(space.uint_w(code)) for code in space.unpackiterable(w_pattern_codes)] return space.newbool(match(space, w_state, pattern_codes)) def match(space, state, pattern_codes): # Optimization: Check string length. pattern_codes[3] contains the # minimum length for a string to possibly match. - if intmask(pattern_codes[0]) == OPCODE_INFO and intmask(pattern_codes[3]) > 0: - if state.end - state.string_position < intmask(pattern_codes[3]): + if pattern_codes[0] == OPCODE_INFO and pattern_codes[3] > 0: + if state.end - state.string_position < pattern_codes[3]: return False state.context_stack.append(MatchContext(space, state, pattern_codes)) has_matched = MatchContext.UNDECIDED @@ -1164,7 +1161,7 @@ shift = 4 else: shift = 5 - block_value = ctx.peek_code_uint(block * (32 / CODESIZE) + block_value = ctx.peek_code(block * (32 / CODESIZE) + ((char_code & 255) >> shift)) if block_value & (1 << (char_code & ((8 * CODESIZE) - 1))): return ctx.set_ok From ale at codespeak.net Sun Aug 28 11:08:12 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Sun, 28 Aug 2005 11:08:12 +0200 (CEST) Subject: [pypy-svn] r16944 - pypy/release/0.7.x/pypy/tool/pytest Message-ID: <20050828090812.51C2B27B4B@code1.codespeak.net> Author: ale Date: Sun Aug 28 11:08:11 2005 New Revision: 16944 Modified: pypy/release/0.7.x/pypy/tool/pytest/genreportdata.py Log: Make it possible to run genreportdata without svn access Modified: pypy/release/0.7.x/pypy/tool/pytest/genreportdata.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/genreportdata.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/genreportdata.py Sun Aug 28 11:08:11 2005 @@ -1,5 +1,6 @@ import autopath import py +import sys mydir = py.magic.autopath().dirpath().realpath() from pypy.tool.pytest import htmlreport from pypy.tool.pytest import confpath @@ -7,11 +8,14 @@ if __name__ == '__main__': testresultdir = confpath.testresultdir assert testresultdir.check(dir=1) - - resultwc = py.path.svnwc(testresultdir) - - print "updating", resultwc - resultwc.update() + try: + resultwc = py.path.svnwc(testresultdir) + print "updating", resultwc + resultwc.update() + except KeyboardInterrupt, RuntimeError: + raise + except Exception,e: #py.process.ExecutionFailed,e: + print >> sys.stderr, "Warning: ",e #Subversion update failed" print "traversing", mydir rep = htmlreport.HtmlReport() From rxe at codespeak.net Sun Aug 28 11:16:01 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 28 Aug 2005 11:16:01 +0200 (CEST) Subject: [pypy-svn] r16946 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050828091601.96B4127B4B@code1.codespeak.net> Author: rxe Date: Sun Aug 28 11:16:01 2005 New Revision: 16946 Modified: pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh Log: Make executable Modified: pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh (original) +++ pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh Sun Aug 28 11:16:01 2005 @@ -1,3 +1,4 @@ +#!/bin/sh export RTYPERORDER=order,module-list.pedronis # stopping on the first error #python translate_pypy.py -no-c -no-o -text -fork2 From rxe at codespeak.net Sun Aug 28 11:20:34 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 28 Aug 2005 11:20:34 +0200 (CEST) Subject: [pypy-svn] r16947 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050828092034.1510D27B4B@code1.codespeak.net> Author: rxe Date: Sun Aug 28 11:20:33 2005 New Revision: 16947 Modified: pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh (props changed) Log: really set executable this time (i hope!) From nik at codespeak.net Sun Aug 28 11:21:39 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sun, 28 Aug 2005 11:21:39 +0200 (CEST) Subject: [pypy-svn] r16948 - pypy/release/0.7.x/pypy/module/_sre/test Message-ID: <20050828092139.8396727B4B@code1.codespeak.net> Author: nik Date: Sun Aug 28 11:21:39 2005 New Revision: 16948 Modified: pypy/release/0.7.x/pypy/module/_sre/test/test_interp_sre.py Log: fixed typo in test Modified: pypy/release/0.7.x/pypy/module/_sre/test/test_interp_sre.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_sre/test/test_interp_sre.py (original) +++ pypy/release/0.7.x/pypy/module/_sre/test/test_interp_sre.py Sun Aug 28 11:21:39 2005 @@ -95,6 +95,6 @@ assert [0, 1] == isre.to_byte_array(256) assert [2, 1] == isre.to_byte_array(258) else: - assert [1, 0, 0, ] == isre.to_byte_array(1) + assert [1, 0, 0, 0] == isre.to_byte_array(1) assert [0, 1, 0, 0] == isre.to_byte_array(256) assert [4, 3, 2, 1] == isre.to_byte_array(0x01020304) From pedronis at codespeak.net Sun Aug 28 11:27:11 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 11:27:11 +0200 (CEST) Subject: [pypy-svn] r16949 - pypy/release/0.7.x/pypy/tool/test Message-ID: <20050828092711.4C7CC27B4B@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 11:27:10 2005 New Revision: 16949 Modified: pypy/release/0.7.x/pypy/tool/test/test_getdocstrings.py Log: make the test more robust Modified: pypy/release/0.7.x/pypy/tool/test/test_getdocstrings.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/test/test_getdocstrings.py (original) +++ pypy/release/0.7.x/pypy/tool/test/test_getdocstrings.py Sun Aug 28 11:27:10 2005 @@ -17,13 +17,17 @@ self.fd1.close() def test_mkfilelist(self): - assert mk_std_filelist() == [ + l = mk_std_filelist() + l.sort() + check = [ 'basestringtype.py', 'unicodetype.py', 'inttype.py', 'nonetype.py', 'longtype.py', 'slicetype.py', 'itertype.py', 'floattype.py', 'dicttype.py', 'dictproxytype.py', 'tupletype.py', 'booltype.py', 'objecttype.py', 'stringtype.py', 'listtype.py'] + check.sort() + assert l == check def test_gottestfile(self): s = self.fd1.read() # whole file as string From ac at codespeak.net Sun Aug 28 11:38:32 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 28 Aug 2005 11:38:32 +0200 (CEST) Subject: [pypy-svn] r16952 - pypy/release/0.7.x/pypy/module/_codecs Message-ID: <20050828093832.A905F27B4B@code1.codespeak.net> Author: ac Date: Sun Aug 28 11:38:32 2005 New Revision: 16952 Modified: pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py Log: Fix bad range check. Modified: pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py (original) +++ pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py Sun Aug 28 11:38:32 2005 @@ -1690,7 +1690,7 @@ else: #ifndef Py_UNICODE_WIDE if sys.maxunicode > 0xffff: - if (x > 0x10000): + if (x > sys.maxunicode): res = unicode_call_errorhandler( errors, "rawunicodeescape", "\\Uxxxxxxxx out of range", s, size, pos, pos+1) From rxe at codespeak.net Sun Aug 28 11:44:44 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 28 Aug 2005 11:44:44 +0200 (CEST) Subject: [pypy-svn] r16953 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828094444.D97AB27B4B@code1.codespeak.net> Author: rxe Date: Sun Aug 28 11:44:44 2005 New Revision: 16953 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: Some mods and redundancy checks to the llvm getting started parts. Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 11:44:44 2005 @@ -359,30 +359,34 @@ avaiable in C (e.g. int) with low level versions. This can also be ommited although it is not recommended. - translating the flow graph to LLVM code +++++++++++++++++++++++++++++++++++++++ -If you feel adventureous (and have `LLVM installed`_ and on your path) you can -also try to compile the graph with LLVM_ (low level virtual machine). This -works nearly as well as for the c backend. There is a restriction, though: The -return type and the arguments of the entry function has to be an int, float or -bool. To try it do:: +To translate for LLVM (low level virtual machine) you must first have `LLVM +installed with the CVS version`. The LLVM backend is still experimental. +However, it is very close to C backend functionality. Calling compiled LLVM +code from CPython is more restrictive than the C backend - the return type and +the arguments of the entry function must be ints, floats or bools. The +emphasis of the LLVM backend is to compile standalone executables - please see +the pypy/translate/llvm/demo directory for examples. + +Here is a simple example to try:: >>> t = Translator(test.my_gcd) >>> a = t.annotate([int, int]) - >>> a.simplify() >>> t.specialize() >>> print t.llvm() <... really huge amount of LLVM code ...> - >>> f = t.llvmcompile(optimize=True) - >>> f(15, 10) + >>> f = t.llvmcompile() + >>> f.pypy_my_gcd_wrapper(15, 10) 5 -In contrast to the C backend this works only for fully annotated and -specialized graphs. +Please note that you dont need the CFrontend to compile, make tools-only. + +.. _LLVM: +.. _`LLVM installed with the CVS version`: http://llvm.cs.uiuc.edu/releases/ a slightly larger example +++++++++++++++++++++++++ @@ -454,11 +458,6 @@ * ``-text``: don't show the flowgraph after the translation is done. This is useful if you don't have pygame installed. - * ``-llvm``: produce code for LLVM_ instead of for C. One of the biggest - things not working there is threading. Be aware that you will - need to install llvm from CVS to successfully translate to - a LLVM target. - * ``-boehm``: use the `Boehm-Demers-Weiser garbage collector`_ instead of our own reference counting implementation. @@ -473,6 +472,9 @@ python translate_pypy.py targetrpystone2 +or to create standalone executable using the experimental LLVM_ compiler infrastructure. + + ./run_pypy-llvm.sh .. _`start reading sources`: @@ -535,29 +537,6 @@ pygame: http://www.pygame.org/download.shtml -.. _LLVM: -.. _`LLVM installed`: - -LLVM -+++++ - -LLVM is used by the optional `PyPy/LLVM backend`_ to generate -processor indepdendant machine level code for the `low level -virtual machine`_. LLVM can be quite annoying to install: you -need a fairly recent version of GCC to compile it and there -can be severe problems under windows. **NOTE: To use the LLVM -backend of PyPy you don't need the GCC front end of LLVM, only -LLVM itself**. Here are detailed instructions on how to -install: - - http://llvm.cs.uiuc.edu/docs/GettingStarted.html - -If you run into problems with the installation the `LLVM -mailing list`_ is very helpful and friendly. Note also that -the PyPy LLVM backend was developed using LLVM 1.4 but it -seems to work with LLVM 1.5. Nobody ever tried an older -version. - CLISP +++++++ From ac at codespeak.net Sun Aug 28 11:47:40 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 28 Aug 2005 11:47:40 +0200 (CEST) Subject: [pypy-svn] r16954 - pypy/release/0.7.x/pypy/module/_codecs Message-ID: <20050828094740.793BE27B4B@code1.codespeak.net> Author: ac Date: Sun Aug 28 11:47:40 2005 New Revision: 16954 Modified: pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py Log: Fix utf-8 encoder. Modified: pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py (original) +++ pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py Sun Aug 28 11:47:40 2005 @@ -1303,6 +1303,8 @@ p += (chr((0x80 | ((ord(ch) >> 6) & 0x3f)))) p += (chr((0x80 | (ord(ch) & 0x3f)))) continue + else: + p.extend(encodeUCS4(ord(ch))) return p def encodeUCS4(ch): From pedronis at codespeak.net Sun Aug 28 11:48:34 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 11:48:34 +0200 (CEST) Subject: [pypy-svn] r16955 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828094834.155E427B4B@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 11:48:33 2005 New Revision: 16955 Modified: pypy/release/0.7.x/pypy/doc/architecture.txt Log: this goal was basically achieved Modified: pypy/release/0.7.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.7.x/pypy/doc/architecture.txt Sun Aug 28 11:48:33 2005 @@ -321,7 +321,7 @@ RPython, the Flow Object Space and translation ============================================== -One of PyPy's now-short-term objectives is to enable translation of our +One of PyPy's now achieved objectives is to enable translation of our bytecode interpreter and standard object space into a lower-level language. In order for our translation and type inference mechanisms to work effectively, we need to restrict the dynamism of our interpreter-level From ludal at codespeak.net Sun Aug 28 11:49:52 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sun, 28 Aug 2005 11:49:52 +0200 (CEST) Subject: [pypy-svn] r16957 - in pypy/release/0.7.x/pypy: interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050828094952.2FAA327B4B@code1.codespeak.net> Author: ludal Date: Sun Aug 28 11:49:50 2005 New Revision: 16957 Modified: pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py Log: correct some syntaxerror() calls Modified: pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py Sun Aug 28 11:49:50 2005 @@ -1210,11 +1210,11 @@ if t == token.LSQB: return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY) - self.syntaxerror( 'unknown node type: %s' % t, primaryNode) + self.syntaxerror( 'unknown node type: %s' % t, nodelist[1]) def com_select_member(self, primaryNode, nodelist): if nodelist[0] != token.NAME: - self.syntaxerror( "member must be a name", primaryNode) + self.syntaxerror( "member must be a name", nodelist[0]) return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) def com_call_function(self, primaryNode, nodelist): @@ -1233,7 +1233,7 @@ and len(node) == 3 and node[2][0] == symbol.gen_for: # allow f(x for x in y), but reject f(x for x in y, 1) # should use f((x for x in y), 1) instead of f(x for x in y, 1) - self.syntaxerror( 'generator expression needs parenthesis', primaryNode) + self.syntaxerror( 'generator expression needs parenthesis', nodelist[0]) args.append(result) else: @@ -1249,14 +1249,14 @@ i = i + 3 if tok[0]==token.STAR: if star_node is not None: - self.syntaxerror( 'already have the varargs indentifier', primaryNode) + self.syntaxerror( 'already have the varargs indentifier', nodelist[0] ) star_node = self.com_node(ch) elif tok[0]==token.DOUBLESTAR: if dstar_node is not None: - self.syntaxerror( 'already have the kwargs indentifier', primaryNode) + self.syntaxerror( 'already have the kwargs indentifier', nodelist[0] ) dstar_node = self.com_node(ch) else: - self.syntaxerror( 'unknown node type: %s' % tok, primaryNode) + self.syntaxerror( 'unknown node type: %s' % tok, nodelist[0] ) return CallFunc(primaryNode, args, star_node, dstar_node, lineno=extractLineNo(nodelist)) Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py Sun Aug 28 11:49:50 2005 @@ -1206,11 +1206,11 @@ if t == token.LSQB: return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY) - self.syntaxerror( 'unknown node type: %s' % t, primaryNode) + self.syntaxerror( 'unknown node type: %s' % t, nodelist[1]) def com_select_member(self, primaryNode, nodelist): if nodelist[0] != token.NAME: - self.syntaxerror( "member must be a name", primaryNode) + self.syntaxerror( "member must be a name", nodelist[0]) return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) def com_call_function(self, primaryNode, nodelist): @@ -1229,7 +1229,7 @@ and len(node) == 3 and node[2][0] == symbol.gen_for: # allow f(x for x in y), but reject f(x for x in y, 1) # should use f((x for x in y), 1) instead of f(x for x in y, 1) - self.syntaxerror( 'generator expression needs parenthesis', primaryNode) + self.syntaxerror( 'generator expression needs parenthesis', nodelist[0]) args.append(result) else: @@ -1245,14 +1245,14 @@ i = i + 3 if tok[0]==token.STAR: if star_node is not None: - self.syntaxerror( 'already have the varargs indentifier', primaryNode) + self.syntaxerror( 'already have the varargs indentifier', nodelist[0] ) star_node = self.com_node(ch) elif tok[0]==token.DOUBLESTAR: if dstar_node is not None: - self.syntaxerror( 'already have the kwargs indentifier', primaryNode) + self.syntaxerror( 'already have the kwargs indentifier', nodelist[0] ) dstar_node = self.com_node(ch) else: - self.syntaxerror( 'unknown node type: %s' % tok, primaryNode) + self.syntaxerror( 'unknown node type: %s' % tok, nodelist[0] ) return CallFunc(primaryNode, args, star_node, dstar_node, lineno=extractLineNo(nodelist)) From hpk at codespeak.net Sun Aug 28 11:50:55 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 11:50:55 +0200 (CEST) Subject: [pypy-svn] r16958 - pypy/tag/pypy-0.7.0-beta Message-ID: <20050828095055.C6A4E27B4B@code1.codespeak.net> Author: hpk Date: Sun Aug 28 11:50:55 2005 New Revision: 16958 Added: pypy/tag/pypy-0.7.0-beta/ - copied from r16957, pypy/release/0.7.x/ Log: tagging as beta From hpk at codespeak.net Sun Aug 28 11:59:15 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 11:59:15 +0200 (CEST) Subject: [pypy-svn] r16962 - pypy/release/0.7.x Message-ID: <20050828095915.C2B6627B4B@code1.codespeak.net> Author: hpk Date: Sun Aug 28 11:59:15 2005 New Revision: 16962 Modified: pypy/release/0.7.x/README Log: fix readme local file link Modified: pypy/release/0.7.x/README ============================================================================== --- pypy/release/0.7.x/README (original) +++ pypy/release/0.7.x/README Sun Aug 28 11:59:15 2005 @@ -22,7 +22,7 @@ Our online release announcement has some more information about the specific PyPy-0.7.0 release: - pypy/documentation/release-0.7.0.txt or + pypy/doc/release-0.7.0.txt or http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html Please note that the last 9 months of PyPy development From pedronis at codespeak.net Sun Aug 28 12:02:36 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 12:02:36 +0200 (CEST) Subject: [pypy-svn] r16966 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828100236.F1BF927B4B@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 12:02:36 2005 New Revision: 16966 Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Log: typos Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/release-0.7.0.txt (original) +++ pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Sun Aug 28 12:02:36 2005 @@ -6,7 +6,7 @@ the PyPy development team is happy to announce its first public release of a fully translatable self contained Python implementation. The 0.7 release showcases the results of our -efforts in the last few months since the 0.6 preview releae +efforts in the last few months since the 0.6 preview release which have been partially funded by the European Union: - whole program type inference on our Python Interpreter @@ -24,7 +24,7 @@ What is PyPy (about)? ------------------------------------------------ -PyPy is an MIT-licensed research-oriented reimplementation of +PyPy is a MIT-licensed research-oriented reimplementation of Python written in Python itself, flexible and easy to experiment with. It translates itself to lower level languages. Our goals are to target a large variety of From rxe at codespeak.net Sun Aug 28 12:09:19 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 28 Aug 2005 12:09:19 +0200 (CEST) Subject: [pypy-svn] r16968 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828100919.00FB627B4B@code1.codespeak.net> Author: rxe Date: Sun Aug 28 12:09:18 2005 New Revision: 16968 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: fixes for links Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:09:18 2005 @@ -359,16 +359,22 @@ avaiable in C (e.g. int) with low level versions. This can also be ommited although it is not recommended. +.. _LLVM: + translating the flow graph to LLVM code +++++++++++++++++++++++++++++++++++++++ -To translate for LLVM (low level virtual machine) you must first have `LLVM -installed with the CVS version`. The LLVM backend is still experimental. -However, it is very close to C backend functionality. Calling compiled LLVM -code from CPython is more restrictive than the C backend - the return type and -the arguments of the entry function must be ints, floats or bools. The -emphasis of the LLVM backend is to compile standalone executables - please see -the pypy/translate/llvm/demo directory for examples. +To translate for LLVM (`low level virtual machine`_) you must first have `LLVM +installed with the CVS version`_ - the `how to install LLVM`_ provides some +helpful hints. Please note that you do not need the CFrontend to compile, make +tools-only. + +The LLVM backend is still experimental. However, it is very close to C backend +functionality. Calling compiled LLVM code from CPython is more restrictive +than the C backend - the return type and the arguments of the entry function +must be ints, floats or bools. The emphasis of the LLVM backend is to compile +standalone executables - please see the pypy/translate/llvm/demo directory for +examples. Here is a simple example to try:: @@ -383,10 +389,6 @@ >>> f.pypy_my_gcd_wrapper(15, 10) 5 -Please note that you dont need the CFrontend to compile, make tools-only. - -.. _LLVM: -.. _`LLVM installed with the CVS version`: http://llvm.cs.uiuc.edu/releases/ a slightly larger example +++++++++++++++++++++++++ @@ -472,9 +474,9 @@ python translate_pypy.py targetrpystone2 -or to create standalone executable using the experimental LLVM_ compiler infrastructure. +or to create standalone executable using the experimental LLVM_ compiler infrastructure:: - ./run_pypy-llvm.sh + ./run_pypy-llvm.sh .. _`start reading sources`: @@ -580,6 +582,7 @@ .. _`low level virtual machine`: http://llvm.cs.uiuc.edu/ .. _`how to install LLVM`: http://llvm.cs.uiuc.edu/docs/GettingStarted.html .. _`LLVM mailing list`: http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev +.. _`LLVM installed with the CVS version`: http://llvm.cs.uiuc.edu/releases .. _Dot Graphviz: http://www.research.att.com/sw/tools/graphviz/ From cfbolz at codespeak.net Sun Aug 28 12:10:51 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 12:10:51 +0200 (CEST) Subject: [pypy-svn] r16969 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828101051.1141627B4E@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 12:10:50 2005 New Revision: 16969 Modified: pypy/release/0.7.x/pypy/doc/faq.txt Log: added a faq entry with the tip to remove pyc files and caches Modified: pypy/release/0.7.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/faq.txt (original) +++ pypy/release/0.7.x/pypy/doc/faq.txt Sun Aug 28 12:10:50 2005 @@ -43,5 +43,13 @@ hard-coded for your particular system (including paths), so it's not really suitable for being installed or redistributed. +I am getting strange errors while playing with PyPy, what should I do? + + It seems that a lot of strange, unexplainable problems can be magically + solved by removing all the *.pyc files from the PyPy source tree. Another + thing you can do is removing the pypy/_cache completely. If the error is + persistent and still annoys you after this treatment please send us a bug + report (or even better, a fix :-) + .. _`RPython`: coding-guide.html#rpython .. _`getting-started`: getting-started.html From ludal at codespeak.net Sun Aug 28 12:18:40 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sun, 28 Aug 2005 12:18:40 +0200 (CEST) Subject: [pypy-svn] r16971 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828101840.495B627B46@code1.codespeak.net> Author: ludal Date: Sun Aug 28 12:18:39 2005 New Revision: 16971 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: need to cd into pypy/ to run only pypy's tests (not py's) Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:18:39 2005 @@ -98,7 +98,8 @@ If you want to see if PyPy works on your machine/platform you can simply run PyPy's large test suite with:: - python pypy/test_all.py + cd pypy + python test_all.py test_all.py is just another name for `py.test`_ which is the testing tool that we are using and enhancing for PyPy. From arigo at codespeak.net Sun Aug 28 12:21:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 12:21:30 +0200 (CEST) Subject: [pypy-svn] r16973 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828102130.3CA4627B46@code1.codespeak.net> Author: arigo Date: Sun Aug 28 12:21:29 2005 New Revision: 16973 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: Fixed the svn url to the release/0.7.x branch Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:21:29 2005 @@ -29,9 +29,10 @@ * alternatively run - * ``svn co http://codespeak.net/svn/pypy/release/0.7.0 pypy-0.7.0`` + * ``svn co http://codespeak.net/svn/pypy/release/0.7.x pypy-0.7.x`` + (the 0.7 maintenance branch) -then change to the ``pypy-0.7.0`` directory +then change to the ``pypy-0.7.0`` or ``pypy-0.7.x`` directory and execute the following command line:: python pypy/bin/py.py From cfbolz at codespeak.net Sun Aug 28 12:22:08 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 12:22:08 +0200 (CEST) Subject: [pypy-svn] r16975 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828102208.C7EE127B46@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 12:22:07 2005 New Revision: 16975 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: oops, old library location Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:22:07 2005 @@ -170,7 +170,7 @@ Alternatively, as with regular Python, you can simply give a script name on the command line:: - python py.py ../../lib-python/modified-2.3.4/test/pystone.py 10 + python py.py ../../lib-python/modified-2.4.1/test/pystone.py 10 special PyPy features -------------------------- @@ -286,14 +286,14 @@ Finally, there are the CPython regression tests which you can run like this:: - cd lib-python/2.3.4/test + cd lib-python/2.4.1/test python ../../../pypy/test_all.py -E or if you have `installed py.test`_ then you simply say:: py.test -E -from the lib-python-2.3.4/test directory. +from the lib-python/2.4.1/test directory. .. _`installed py.test`: http://codespeak.net/py/current/doc/getting-started.html From cfbolz at codespeak.net Sun Aug 28 12:27:10 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 12:27:10 +0200 (CEST) Subject: [pypy-svn] r16977 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828102710.8E97327B46@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 12:27:09 2005 New Revision: 16977 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: fix info about pystone Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:27:09 2005 @@ -149,9 +149,7 @@ >>>> from test import pystone >>>> pystone.main(10) -Note that this is a slightly modified version of pystone -- the -original version does not accept the parameter to main(). The -parameter is the number of loops to run through the test, and the +The parameter is the number of loops to run through the test. The default is 50000, which is far too many to run in a reasonable time on the current PyPy implementation. @@ -170,7 +168,7 @@ Alternatively, as with regular Python, you can simply give a script name on the command line:: - python py.py ../../lib-python/modified-2.4.1/test/pystone.py 10 + python py.py ../../lib-python/2.4.1/test/pystone.py 10 special PyPy features -------------------------- From pedronis at codespeak.net Sun Aug 28 12:33:12 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 12:33:12 +0200 (CEST) Subject: [pypy-svn] r16978 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828103312.22ABF27B46@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 12:33:09 2005 New Revision: 16978 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: documentation -> doc don't advertise -E option for running compliancy tests Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:33:09 2005 @@ -68,7 +68,7 @@ This will create a directory named ``pypy-dist``, and will get you the PyPy source in ``pypy-dist/pypy`` and documentation files in -``pypy-dist/pypy/documentation``. +``pypy-dist/pypy/doc``. After checkout you can get a PyPy interpreter via:: @@ -285,11 +285,11 @@ run like this:: cd lib-python/2.4.1/test - python ../../../pypy/test_all.py -E + python ../../../pypy/test_all.py or if you have `installed py.test`_ then you simply say:: - py.test -E + py.test from the lib-python/2.4.1/test directory. From pedronis at codespeak.net Sun Aug 28 12:36:10 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 12:36:10 +0200 (CEST) Subject: [pypy-svn] r16980 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828103610.5AEFC27B46@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 12:36:09 2005 New Revision: 16980 Modified: pypy/release/0.7.x/pypy/doc/faq.txt Log: ReST fix Modified: pypy/release/0.7.x/pypy/doc/faq.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/faq.txt (original) +++ pypy/release/0.7.x/pypy/doc/faq.txt Sun Aug 28 12:36:09 2005 @@ -46,7 +46,7 @@ I am getting strange errors while playing with PyPy, what should I do? It seems that a lot of strange, unexplainable problems can be magically - solved by removing all the *.pyc files from the PyPy source tree. Another + solved by removing all the \*.pyc files from the PyPy source tree. Another thing you can do is removing the pypy/_cache completely. If the error is persistent and still annoys you after this treatment please send us a bug report (or even better, a fix :-) From cfbolz at codespeak.net Sun Aug 28 12:46:47 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 12:46:47 +0200 (CEST) Subject: [pypy-svn] r16981 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828104647.8DBB427B46@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 12:46:46 2005 New Revision: 16981 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: oops, the test didn't exists anymore Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:46:46 2005 @@ -273,7 +273,7 @@ Alternatively, you may run subtests by going to the correct subdirectory and running them individually:: - python test_all.py module/test/test_builtin.py + python test_all.py interpreter/test/test_pyframe.py ``test_all.py`` is actually just a synonym for `py.test`_ which is our external testing tool. If you have installed that you From cfbolz at codespeak.net Sun Aug 28 12:53:36 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 12:53:36 +0200 (CEST) Subject: [pypy-svn] r16982 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828105336.CCEDB27B46@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 12:53:35 2005 New Revision: 16982 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: tell the poor people that try to run the CPython regression tests that they need the testresult dir Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 12:53:35 2005 @@ -282,7 +282,7 @@ run all tests below the current directory. Finally, there are the CPython regression tests which you can -run like this:: +run like this (this will take a hours and hours and hours):: cd lib-python/2.4.1/test python ../../../pypy/test_all.py @@ -291,7 +291,9 @@ py.test -from the lib-python/2.4.1/test directory. +from the lib-python/2.4.1/test directory. You need to have a checkout of the +testresult directory. Running one of the above commands tells you how to +proceed. .. _`installed py.test`: http://codespeak.net/py/current/doc/getting-started.html From hpk at codespeak.net Sun Aug 28 12:59:10 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 12:59:10 +0200 (CEST) Subject: [pypy-svn] r16983 - pypy/release/0.7.x/pypy/tool/pytest/test Message-ID: <20050828105910.B418F27B46@code1.codespeak.net> Author: hpk Date: Sun Aug 28 12:59:09 2005 New Revision: 16983 Modified: pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py Log: skip tests that depends on mime-parsing which does not work on python 2.4 currently apparently Modified: pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py Sun Aug 28 12:59:09 2005 @@ -2,10 +2,12 @@ import py #from pypy.tool.pytest.confpath import testresultdir from pypy.tool.pytest.result import ResultFromMime -testpath = py.path.local( __file__).parts()[-2] -testpath=testpath.join( 'data') +testpath = py.magic.autopath().dirpath('data') class TestResultCache: + def setup_class(self): + if py.std.sys.version_info >= (2,4): + py.test.skip("does not work on python 2.4 and greater currently") def test_timeout(self): test = ResultFromMime(testpath.join('test___all__.txt')) From arigo at codespeak.net Sun Aug 28 12:59:39 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 12:59:39 +0200 (CEST) Subject: [pypy-svn] r16984 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828105939.A3F2627B46@code1.codespeak.net> Author: arigo Date: Sun Aug 28 12:59:38 2005 New Revision: 16984 Modified: pypy/release/0.7.x/pypy/doc/translation.txt Log: Quick updates about the GenC status, and url fix. Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Sun Aug 28 12:59:38 2005 @@ -42,7 +42,7 @@ low-level operations over low-level types (close to the C types: struct, array, pointer...). - One of the Code Generators (XXX not documented yet) turns the +5. One of the Code Generators (back-ends) turns the optionally annotated/typed flow graphs and produces a source file in a lower-level language: C_, LLVM_, `Common Lisp`_, Pyrex_, Java_, or `Python again`_ (this is used in PyPy to turn sufficiently RPythonic @@ -961,7 +961,7 @@ The C Back-End ============== -http://codespeak.net/pypy/dist/pypy/translator/genc/ +http://codespeak.net/pypy/dist/pypy/translator/c/ Overview @@ -974,8 +974,11 @@ graph according to the annotations, replacing operations with lower-level C-ish equivalents. -XXX GenC is currently in the process of being updated to use the RPython Typer. -More documentation needed when this is done. But the basic principle of creating +This version of GenC, using the RPython Typer, is recent but quite stable and +already flexible (for example, it can produce code with two different memory +management policies, reference-counting or using the Boehm garabage collector). + +GenC is not documented at the moment. The basic principle of creating code from flowgraphs is similar to the `Python back-end`_. From arigo at codespeak.net Sun Aug 28 13:01:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 13:01:14 +0200 (CEST) Subject: [pypy-svn] r16985 - pypy/release/0.7.x/pypy/translator Message-ID: <20050828110114.6F8D727B47@code1.codespeak.net> Author: arigo Date: Sun Aug 28 13:01:13 2005 New Revision: 16985 Modified: pypy/release/0.7.x/pypy/translator/translator.py Log: Catch all errors while trying inspect.getsource(). It breaks randomly here and there and shows up sometimes when using %r formatting :-( ludal will look into CPython's inspect.py/tokenize.py... Modified: pypy/release/0.7.x/pypy/translator/translator.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/translator.py (original) +++ pypy/release/0.7.x/pypy/translator/translator.py Sun Aug 28 13:01:13 2005 @@ -73,11 +73,11 @@ print self.flowgraphs[func] = graph self.functions.append(func) + graph.func = func try: import inspect - graph.func = func graph.source = inspect.getsource(func) - except IOError: + except: pass # e.g. when func is defined interactively if called_by: self.callgraph[called_by, func, call_tag] = called_by, func From hpk at codespeak.net Sun Aug 28 13:02:27 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 13:02:27 +0200 (CEST) Subject: [pypy-svn] r16986 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828110227.A87FE27B47@code1.codespeak.net> Author: hpk Date: Sun Aug 28 13:02:27 2005 New Revision: 16986 Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Log: be more specific in the title of the release annoucnement Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/release-0.7.0.txt (original) +++ pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Sun Aug 28 13:02:27 2005 @@ -1,4 +1,4 @@ -pypy-0.7.0: first self-contained Python Implementation +pypy-0.7.0: first PyPy-generated Python Implementations ============================================================== What was once just an idea between a few people discussing From ludal at codespeak.net Sun Aug 28 13:03:55 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sun, 28 Aug 2005 13:03:55 +0200 (CEST) Subject: [pypy-svn] r16987 - in pypy/release/0.7.x/pypy: interpreter/stablecompiler lib/_stablecompiler Message-ID: <20050828110355.C8D5927B47@code1.codespeak.net> Author: ludal Date: Sun Aug 28 13:03:53 2005 New Revision: 16987 Modified: pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py Log: refix syntax errors Modified: pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py Sun Aug 28 13:03:53 2005 @@ -1233,7 +1233,7 @@ and len(node) == 3 and node[2][0] == symbol.gen_for: # allow f(x for x in y), but reject f(x for x in y, 1) # should use f((x for x in y), 1) instead of f(x for x in y, 1) - self.syntaxerror( 'generator expression needs parenthesis', nodelist[0]) + self.syntaxerror( 'generator expression needs parenthesis', node) args.append(result) else: @@ -1249,14 +1249,14 @@ i = i + 3 if tok[0]==token.STAR: if star_node is not None: - self.syntaxerror( 'already have the varargs indentifier', nodelist[0] ) + self.syntaxerror( 'already have the varargs indentifier', tok ) star_node = self.com_node(ch) elif tok[0]==token.DOUBLESTAR: if dstar_node is not None: - self.syntaxerror( 'already have the kwargs indentifier', nodelist[0] ) + self.syntaxerror( 'already have the kwargs indentifier', tok ) dstar_node = self.com_node(ch) else: - self.syntaxerror( 'unknown node type: %s' % tok, nodelist[0] ) + self.syntaxerror( 'unknown node type: %s' % tok, tok ) return CallFunc(primaryNode, args, star_node, dstar_node, lineno=extractLineNo(nodelist)) @@ -1266,7 +1266,7 @@ return 0, self.com_generator_expression(test, nodelist[2]) if len(nodelist) == 2: if kw: - self.syntaxerror( "non-keyword arg after keyword arg", nodelist[0]) + self.syntaxerror( "non-keyword arg after keyword arg", nodelist ) return 0, self.com_node(nodelist[1]) result = self.com_node(nodelist[3]) n = nodelist[1] Modified: pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py ============================================================================== --- pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py (original) +++ pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py Sun Aug 28 13:03:53 2005 @@ -1229,7 +1229,7 @@ and len(node) == 3 and node[2][0] == symbol.gen_for: # allow f(x for x in y), but reject f(x for x in y, 1) # should use f((x for x in y), 1) instead of f(x for x in y, 1) - self.syntaxerror( 'generator expression needs parenthesis', nodelist[0]) + self.syntaxerror( 'generator expression needs parenthesis', node) args.append(result) else: @@ -1245,14 +1245,14 @@ i = i + 3 if tok[0]==token.STAR: if star_node is not None: - self.syntaxerror( 'already have the varargs indentifier', nodelist[0] ) + self.syntaxerror( 'already have the varargs indentifier', tok ) star_node = self.com_node(ch) elif tok[0]==token.DOUBLESTAR: if dstar_node is not None: - self.syntaxerror( 'already have the kwargs indentifier', nodelist[0] ) + self.syntaxerror( 'already have the kwargs indentifier', tok ) dstar_node = self.com_node(ch) else: - self.syntaxerror( 'unknown node type: %s' % tok, nodelist[0] ) + self.syntaxerror( 'unknown node type: %s' % tok, tok ) return CallFunc(primaryNode, args, star_node, dstar_node, lineno=extractLineNo(nodelist)) @@ -1262,7 +1262,7 @@ return 0, self.com_generator_expression(test, nodelist[2]) if len(nodelist) == 2: if kw: - self.syntaxerror( "non-keyword arg after keyword arg", nodelist[0]) + self.syntaxerror( "non-keyword arg after keyword arg", nodelist ) return 0, self.com_node(nodelist[1]) result = self.com_node(nodelist[3]) n = nodelist[1] From rxe at codespeak.net Sun Aug 28 13:08:28 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 28 Aug 2005 13:08:28 +0200 (CEST) Subject: [pypy-svn] r16989 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828110828.C9AA627B47@code1.codespeak.net> Author: rxe Date: Sun Aug 28 13:08:28 2005 New Revision: 16989 Modified: pypy/release/0.7.x/pypy/doc/translation.txt Log: rxe/ericvrp Added part about LLVM translation Modified: pypy/release/0.7.x/pypy/doc/translation.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/translation.txt (original) +++ pypy/release/0.7.x/pypy/doc/translation.txt Sun Aug 28 13:08:28 2005 @@ -562,7 +562,7 @@ --------------- The RPython Typer uses a standard low-level model which we believe can -correspond rather directly to various target languages from C to LLVM to Java. +correspond rather directly to various target languages from C to LLVM_ to Java. This model is implemented in the first part of `rpython/lltype.py`_. The second part of `rpython/lltype.py`_ is a runnable implementation of these @@ -990,11 +990,33 @@ http://codespeak.net/pypy/dist/pypy/translator/llvm/ -XXX to be written +For information on getting started on the LLVM (`low level virtual machine`_) +backend - please see `here`_. + +Overview +-------- +Similar to the task of GenC, GenLLVM translates a flow graph to low level LLVM +bytecode. GenLLVM requires annotation and the `RPython Typer`_ pass, to modify +the annontated flow graph to replace operations with lower-level equivalents +which are suitable to be easily translated to LLVM bytecode. + +History +------- +The LLVM backend would not have been possible without all the people +contributing to PyPy. Carl Friedrich did an amazing amount of groundwork during +the first half of 2005. Carl Friedrich and Holger then initiated a revamped +version based on the new `RPython Typer`_ flow graph. Significant progress was +made during the Gothenburg sprint - and then the following 6 weeks Eric and +Richard worked on it, achieving a standalone executable just prior to the +Heidelberg sprint. During the Heildelberg sprint Eric and Richard mainly +worked on sharing the backend external code with GenC. .. _`Python again`: .. _`Python back-end`: +.. _`low level virtual machine`: http://llvm.cs.uiuc.edu/ +.. _`here`: getting-started.html#translating-the-flow-graph-to-llvm-code + The Interplevel Back-End ======================== From cfbolz at codespeak.net Sun Aug 28 13:19:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 13:19:16 +0200 (CEST) Subject: [pypy-svn] r16990 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828111916.C5BA727B47@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 13:19:16 2005 New Revision: 16990 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: tell about the needed internet connection. add an example on how to run the compiled version of is_perfect_number Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 13:19:16 2005 @@ -314,10 +314,13 @@ sufficiently static Python programs into low-level code. To be able to use it you need to: - * Download and install `Dot Graphviz`_. - * Download and install Pygame_ if you do not already have it. + * Have an internet connection. The flowgraph viewer connects to + codespeak.net and lets it convert the flowgraph by a patched version of + `Dot Graphviz`_ that does not crash. This is only needed if you want to + look at the flowgraphs. + To start the interactive translator do:: cd pypy/bin @@ -359,7 +362,12 @@ The first command replaces operations with variables of types that are avaiable in C (e.g. int) with low level versions. This can also be ommited -although it is not recommended. +although it is not recommended. To try out the compiled version:: + + >>> f(5) + False + >>> f(6) + True .. _LLVM: From hpk at codespeak.net Sun Aug 28 13:20:13 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 13:20:13 +0200 (CEST) Subject: [pypy-svn] r16991 - pypy/release/0.7.x/pypy/tool Message-ID: <20050828112013.3F94B27B4B@code1.codespeak.net> Author: hpk Date: Sun Aug 28 13:20:12 2005 New Revision: 16991 Modified: pypy/release/0.7.x/pypy/tool/makerelease.py Log: fix to generate correct line endings Modified: pypy/release/0.7.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.7.x/pypy/tool/makerelease.py Sun Aug 28 13:20:12 2005 @@ -62,7 +62,7 @@ out = cexec("rsync %(fn)s code2.codespeak.net:%(ddir)s" % locals()) -def forced_export(BASEURL, target, lineend="CR"): +def forced_export(BASEURL, target, lineend="LF"): if target.check(dir=1): log("removing", target) target.remove() @@ -79,7 +79,7 @@ target = tmpdir.join(ver) - forced_export(BASEURL, target, lineend="CR") + forced_export(BASEURL, target, lineend="LF") target_targz = maketargz(target) assert target_targz.check(file=1) copydownload(target_targz) From rxe at codespeak.net Sun Aug 28 13:24:09 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 28 Aug 2005 13:24:09 +0200 (CEST) Subject: [pypy-svn] r16992 - pypy/release/0.7.x/pypy/translator Message-ID: <20050828112409.F221227B4B@code1.codespeak.net> Author: rxe Date: Sun Aug 28 13:24:09 2005 New Revision: 16992 Modified: pypy/release/0.7.x/pypy/translator/translator.py Log: oups forget to check this in :-( Modified: pypy/release/0.7.x/pypy/translator/translator.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/translator.py (original) +++ pypy/release/0.7.x/pypy/translator/translator.py Sun Aug 28 13:24:09 2005 @@ -204,7 +204,7 @@ raise ValueError, "function has to be annotated." gen = GenLLVM(self) filename = gen.gen_llvm_source() - f = open(filename, "r") + f = open(str(filename), "r") result = f.read() f.close() return result From tismer at codespeak.net Sun Aug 28 13:33:59 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 28 Aug 2005 13:33:59 +0200 (CEST) Subject: [pypy-svn] r16994 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050828113359.95E2727B47@code1.codespeak.net> Author: tismer Date: Sun Aug 28 13:33:58 2005 New Revision: 16994 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: small fix for .exe naming in windows Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Sun Aug 28 13:33:58 2005 @@ -330,7 +330,10 @@ return display.run, show, async_quit, pygame.quit - +def mkexename(name): + if sys.platform == 'win32': + name += '.exe' + return name if __name__ == '__main__': @@ -660,8 +663,10 @@ c_entry_point = t.ccompile(standalone=standalone, gcpolicy=gcpolicy) if standalone: # xxx fragile and messy import shutil - shutil.move(c_entry_point, 'pypy-c') - c_entry_point = './pypy-c' + exename = mkexename(c_entry_point) + newexename = mkexename('./pypy-c') + shutil.move(exename, newexename) + c_entry_point = newexename update_usession_dir() if not options['-o']: print 'Running!' From cfbolz at codespeak.net Sun Aug 28 13:36:11 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 13:36:11 +0200 (CEST) Subject: [pypy-svn] r16995 - pypy/release/0.7.x/pypy/bin Message-ID: <20050828113611.DCA8427B47@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 13:36:10 2005 New Revision: 16995 Modified: pypy/release/0.7.x/pypy/bin/translator.py Log: fix usage string Modified: pypy/release/0.7.x/pypy/bin/translator.py ============================================================================== --- pypy/release/0.7.x/pypy/bin/translator.py (original) +++ pypy/release/0.7.x/pypy/bin/translator.py Sun Aug 28 13:36:10 2005 @@ -24,10 +24,12 @@ t.call(arg) # call original function t.dis() # bytecode disassemble - t.specialize() # use low level operations (for C only) + t.specialize() # use low level operations f = t.ccompile() # C compilation - f = t.llvmcompile() # LLVM compilation - assert f(arg) == t.call(arg) # sanity check + mod = t.llvmcompile() # LLVM compilation + assert f(arg) == func(arg) # sanity check (for C) + assert mod.pypy_func_wrapper(arg) == func(arg) # sanity check (for LLVM) + Some functions are provided for the benefit of interactive testing. Try dir(test) for list of current snippets. From tismer at codespeak.net Sun Aug 28 13:39:50 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 28 Aug 2005 13:39:50 +0200 (CEST) Subject: [pypy-svn] r16997 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050828113950.5BD9B27B47@code1.codespeak.net> Author: tismer Date: Sun Aug 28 13:39:49 2005 New Revision: 16997 Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Log: just a little more problem due to "/" vs. "\" Modified: pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py Sun Aug 28 13:39:49 2005 @@ -332,7 +332,7 @@ def mkexename(name): if sys.platform == 'win32': - name += '.exe' + name = os.path.normpath(name + '.exe') return name if __name__ == '__main__': From cfbolz at codespeak.net Sun Aug 28 13:41:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 13:41:16 +0200 (CEST) Subject: [pypy-svn] r16998 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828114116.8B7D927B47@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 13:41:15 2005 New Revision: 16998 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: remove mention pystone2 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 13:41:15 2005 @@ -480,11 +480,9 @@ cd pypy/translator/goal python translate_pypy.py targetrpystone -or a simplified, scaled-down version:: - python translate_pypy.py targetrpystone2 - -or to create standalone executable using the experimental LLVM_ compiler infrastructure:: +To create a standalone executable using the experimental LLVM_ compiler +infrastructure:: ./run_pypy-llvm.sh From hpk at codespeak.net Sun Aug 28 13:43:16 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 13:43:16 +0200 (CEST) Subject: [pypy-svn] r16999 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828114316.1D17727B47@code1.codespeak.net> Author: hpk Date: Sun Aug 28 13:43:15 2005 New Revision: 16999 Modified: pypy/release/0.7.x/pypy/doc/coding-guide.txt Log: renaming of mentions of 2.3.4 -> 2.4.1 Modified: pypy/release/0.7.x/pypy/doc/coding-guide.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/coding-guide.txt (original) +++ pypy/release/0.7.x/pypy/doc/coding-guide.txt Sun Aug 28 13:43:15 2005 @@ -531,7 +531,7 @@ Modules visible from application programs are imported from interpreter or application level files. PyPy reuses almost all python -modules of CPython's standard library, currently from version 2.3.4. We +modules of CPython's standard library, currently from version 2.4.1. We sometimes need to `modify modules`_ and - more often - regression tests because they rely on implementation details of CPython. @@ -561,13 +561,13 @@ >>>> import types t>>>> types.__file__ - '/home/hpk/pypy-dist/lib-python/modified-2.3.4/types.py' + '/home/hpk/pypy-dist/lib-python/modified-2.4.1/types.py' >>>> import os faking faking >>>> os.__file__ - '/home/hpk/pypy-dist/lib-python/2.3.4/os.py' + '/home/hpk/pypy-dist/lib-python/2.4.1/os.py' >>>> Module directories / Import order @@ -590,11 +590,11 @@ contains pure Python reimplementation of modules. -*lib-python/modified-2.3.4/* +*lib-python/modified-2.4.1/* The files and tests that we have modified from the CPython library. -*lib-python/2.3.4/* +*lib-python/2.4.1/* The unmodified CPython library. **Never ever checkin anything here**. @@ -609,14 +609,14 @@ by default and CPython has a number of places where it relies on some classes being old-style. -If you want to change a module or test contained in ``lib-python/2.3.4`` -then make sure that you copy the file to our ``lib-python/modified-2.3.4`` +If you want to change a module or test contained in ``lib-python/2.4.1`` +then make sure that you copy the file to our ``lib-python/modified-2.4.1`` directory first. In subversion commandline terms this reads:: - svn cp lib-python/2.3.4/somemodule.py lib-python/modified-2.3.4/ + svn cp lib-python/2.4.1/somemodule.py lib-python/modified-2.4.1/ and subsequently you edit and commit -``lib-python/modified-2.3.4/somemodule.py``. This copying operation is +``lib-python/modified-2.4.1/somemodule.py``. This copying operation is important because it keeps the original CPython tree clean and makes it obvious what we had to change. From tismer at codespeak.net Sun Aug 28 13:52:03 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 28 Aug 2005 13:52:03 +0200 (CEST) Subject: [pypy-svn] r17001 - pypy/dist/pypy/doc Message-ID: <20050828115203.5D37627B4B@code1.codespeak.net> Author: tismer Date: Sun Aug 28 13:52:01 2005 New Revision: 17001 Modified: pypy/dist/pypy/doc/parser.txt pypy/dist/pypy/doc/redirections Log: small rest fixes. There is still an issue that I don't understand and cannot find, yet: UnicodeDecodeError: 'utf8' codec can't decode byte 0xa0 is reported, but such a byte is not in the .txt files ??? Modified: pypy/dist/pypy/doc/parser.txt ============================================================================== --- pypy/dist/pypy/doc/parser.txt (original) +++ pypy/dist/pypy/doc/parser.txt Sun Aug 28 13:52:01 2005 @@ -162,10 +162,13 @@ Main facade functions ~~~~~~~~~~~~~~~~~~~~~ +still empty, but non-empty for ReST Grammar ~~~~~~~ +still empty, but non-empty for ReST + Long term goals =============== @@ -179,6 +182,7 @@ parser implementation --------------------- + We can now build AST trees directly from the parser. Still missing is the ability to easily provide/change building functions easily. The functions are referenced at interpreter level through a dictionnary @@ -187,15 +191,18 @@ compiler implementation ----------------------- + For now we are working at translating the existing compiler module without changing it's design too much. That means we won't have enough flexibility to be able to handle new AST nodes at runtime. parser module ------------- + enhance the parser module interface so that it allows acces to the internal grammar representation, and allows to modify it too. compiler module --------------- + same as above Modified: pypy/dist/pypy/doc/redirections ============================================================================== --- pypy/dist/pypy/doc/redirections (original) +++ pypy/dist/pypy/doc/redirections Sun Aug 28 13:52:01 2005 @@ -1,4 +1,4 @@ -# please make sure this is evaluatable +# please make sure this is evaluable { 'restrictedpy.html': 'coding-guide.html#restricted-python', 'testdesign.html' : 'coding-guide.html#test-design', From tismer at codespeak.net Sun Aug 28 14:00:15 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 28 Aug 2005 14:00:15 +0200 (CEST) Subject: [pypy-svn] r17002 - pypy/dist/pypy/doc Message-ID: <20050828120015.5099327B4D@code1.codespeak.net> Author: tismer Date: Sun Aug 28 14:00:14 2005 New Revision: 17002 Modified: pypy/dist/pypy/doc/test_redirections.py Log: after redirections have (correctly) been made native eol, the test broke, because it reads data as binary by default. Modified: pypy/dist/pypy/doc/test_redirections.py ============================================================================== --- pypy/dist/pypy/doc/test_redirections.py (original) +++ pypy/dist/pypy/doc/test_redirections.py Sun Aug 28 14:00:14 2005 @@ -7,7 +7,7 @@ assert path.new(ext='.txt').check(file=1) def test_eval(): - d = eval(redir.read()) + d = eval(redir.read(mode='r')) return d def test_redirections(): From pedronis at codespeak.net Sun Aug 28 14:06:51 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 14:06:51 +0200 (CEST) Subject: [pypy-svn] r17003 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050828120651.4DD7727B56@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 14:06:50 2005 New Revision: 17003 Modified: pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Log: disabling -boehm thread combination: has not been tested Modified: pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Sun Aug 28 14:06:50 2005 @@ -57,10 +57,15 @@ # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None + if '-boehm' in __main__.options: + print "disabling thread with boehm for stabilitiy (combination not tested)" + usemodules = [] + else: + usemodules = ['thread'] space = StdObjSpace(nofaking=True, compiler="_stable", # lib/_stablecompiler translating=True, - usemodules=['thread'], + usemodules=usemodules, geninterp=geninterp) # manually imports app_main.py filename = os.path.join(this_dir, 'app_main.py') From cfbolz at codespeak.net Sun Aug 28 14:21:37 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 28 Aug 2005 14:21:37 +0200 (CEST) Subject: [pypy-svn] r17005 - pypy/release/0.7.x/pypy/translator/goal Message-ID: <20050828122137.8BCA427B5E@code1.codespeak.net> Author: cfbolz Date: Sun Aug 28 14:21:37 2005 New Revision: 17005 Modified: pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Log: Oumphf. Modified: pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py Sun Aug 28 14:21:37 2005 @@ -57,7 +57,7 @@ # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None - if '-boehm' in __main__.options: + if __main__.options.get('-boehm'): print "disabling thread with boehm for stabilitiy (combination not tested)" usemodules = [] else: From hpk at codespeak.net Sun Aug 28 14:22:20 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 14:22:20 +0200 (CEST) Subject: [pypy-svn] r17006 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828122220.7DFBB27B5F@code1.codespeak.net> Author: hpk Date: Sun Aug 28 14:22:20 2005 New Revision: 17006 Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt Log: link getting-started to final tarball Modified: pypy/release/0.7.x/pypy/doc/getting-started.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/getting-started.txt (original) +++ pypy/release/0.7.x/pypy/doc/getting-started.txt Sun Aug 28 14:22:20 2005 @@ -23,9 +23,9 @@ * download one of - * `pypy-0.7.0-beta.tar.bz2`_ (unix line endings) or - * `pypy-0.7.0-beta.tar.gz`_ (unix line endings) or - * `pypy-0.7.0-beta.zip`_ (windows line-endings) and unpack it + * `pypy-0.7.0.tar.bz2`_ (unix line endings) or + * `pypy-0.7.0.tar.gz`_ (unix line endings) or + * `pypy-0.7.0.zip`_ (windows line-endings) and unpack it * alternatively run @@ -50,11 +50,9 @@ and is not dependant on CPython anymore. .. _`90% of CPythons core language regression tests`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`pypy-0.7.0-beta.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.tar.bz2 .. _`pypy-0.7.0.tar.bz2`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.bz2 .. _`pypy-0.7.0.zip`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.zip -.. _`pypy-0.7.0-beta.zip`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.zip -.. _`pypy-0.7.0-beta.tar.gz`: http://code2.codespeak.net/download/pypy/pypy-0.7.0-beta.tar.gz +.. _`pypy-0.7.0.tar.gz`: http://code2.codespeak.net/download/pypy/pypy-0.7.0.tar.gz Svn-check out & run the latest PyPy as a two-liner -------------------------------------------------- From hpk at codespeak.net Sun Aug 28 14:25:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 28 Aug 2005 14:25:06 +0200 (CEST) Subject: [pypy-svn] r17007 - pypy/release/0.7.0 Message-ID: <20050828122506.DD76527B66@code1.codespeak.net> Author: hpk Date: Sun Aug 28 14:25:06 2005 New Revision: 17007 Added: pypy/release/0.7.0/ - copied from r17006, pypy/release/0.7.x/ Log: tagging the final pypy 0.7.0 release From nik at codespeak.net Sun Aug 28 14:26:28 2005 From: nik at codespeak.net (nik at codespeak.net) Date: Sun, 28 Aug 2005 14:26:28 +0200 (CEST) Subject: [pypy-svn] r17008 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20050828122628.7031927B69@code1.codespeak.net> Author: nik Date: Sun Aug 28 14:26:27 2005 New Revision: 17008 Modified: pypy/dist/pypy/interpreter/pyparser/parsestring.py Log: fixed typo (?) that caused _stablecompiler (and thus translated pypy) to interpret the string "\b" as "'". Modified: pypy/dist/pypy/interpreter/pyparser/parsestring.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/parsestring.py (original) +++ pypy/dist/pypy/interpreter/pyparser/parsestring.py Sun Aug 28 14:26:27 2005 @@ -142,7 +142,7 @@ elif ch == '"': lis.append("'") elif ch == 'b': - lis.append("\'") + lis.append("\010") elif ch == 'f': lis.append('\014') # FF elif ch == 't': From rxe at codespeak.net Sun Aug 28 14:42:55 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sun, 28 Aug 2005 14:42:55 +0200 (CEST) Subject: [pypy-svn] r17010 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828124255.B0D0427B56@code1.codespeak.net> Author: rxe Date: Sun Aug 28 14:42:55 2005 New Revision: 17010 Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Log: Small name typo Modified: pypy/release/0.7.x/pypy/doc/release-0.7.0.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/release-0.7.0.txt (original) +++ pypy/release/0.7.x/pypy/doc/release-0.7.0.txt Sun Aug 28 14:42:55 2005 @@ -86,7 +86,7 @@ Armin Rigo, Samuele Pedroni, Holger Krekel, Christian Tismer, Carl Friedrich Bolz, Michael Hudson, - Erik van Riet Paap, Richard Emslie, + Eric van Riet Paap, Richard Emslie, Anders Chrigstroem, Anders Lehmann, Ludovic Aubry, Adrien Di Mascio, Niklaus Haldimann, Jacob Hallen, From xoraxax at codespeak.net Sun Aug 28 18:16:42 2005 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Sun, 28 Aug 2005 18:16:42 +0200 (CEST) Subject: [pypy-svn] r17013 - pypy/release/0.7.x/pypy/tool/pytest Message-ID: <20050828161642.E243B27B52@code1.codespeak.net> Author: xoraxax Date: Sun Aug 28 18:16:42 2005 New Revision: 17013 Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py Log: Because the test summary is used for core and non-core tests, just say "tests compliancy" instead of "core tests compliancy". Modified: pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py ============================================================================== --- pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py (original) +++ pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py Sun Aug 28 18:16:42 2005 @@ -128,7 +128,7 @@ return html.tr(*[html.td(arg) for arg in args]) sum_passed = sum([x.ratio_of_passed() for x in tests]) - t.append(row(html.b("core tests compliancy"), + t.append(row(html.b("tests compliancy"), html.b("%.2f%%" % (sum_passed/sum100,)))) t.append(row("testmodules passed completely", "%.2f%%" % (ok/sum100))) From tismer at codespeak.net Sun Aug 28 18:16:59 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 28 Aug 2005 18:16:59 +0200 (CEST) Subject: [pypy-svn] r17014 - in pypy/dist/pypy/module/marshal: . test Message-ID: <20050828161659.814D727B56@code1.codespeak.net> Author: tismer Date: Sun Aug 28 18:16:57 2005 New Revision: 17014 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py pypy/dist/pypy/module/marshal/test/test_marshalimpl.py Log: simplified marshal. - no longer trying to be smart about recursion depth at all - only checking for the CPython limit of 5000 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Sun Aug 28 18:16:57 2005 @@ -86,24 +86,11 @@ # PyPy is currently in much bigger trouble, because the # multimethod dispatches cause deeper stack nesting. -# we try to do a true stack limit estimate, assuming that -# one applevel call costs at most APPLEVEL_STACK_COST -# nested calls. - -nesting_limit = sys.getrecursionlimit() -APPLEVEL_STACK_COST = 25 # XXX check if this is true - -CPYTHON_COMPATIBLE = True - -TEST_CONST = 10 - class _Base(object): def raise_exc(self, msg): space = self.space raise OperationError(space.w_ValueError, space.wrap(msg)) -DONT_USE_MM_HACK = True # im_func is not RPython :-( - class Marshaller(_Base): # _annspecialcase_ = "specialize:ctr_location" # polymorphic # does not work with subclassing @@ -113,19 +100,8 @@ ## self.put = putfunc self.writer = writer self.version = version - # account for the applevel that we will call by one more. - self.nesting = ((space.getexecutioncontext().framestack.depth() + 1) - * APPLEVEL_STACK_COST + TEST_CONST) - self.cpy_nesting = 0 # contribution to compatibility + self.nesting = 0 # contribution to compatibility self.stringtable = {} - self.stackless = False - self._stack = None - #self._iddict = {} - # XXX consider adding the dict later when it is needed. - # XXX I would also love to use an IntDict for this, if - # we had that. Otherwise I'd need to either make strings - # from ids (not all that bad) or use a real dict. - # How expensive would that be? ## currently we cannot use a put that is a bound method ## from outside. Same holds for get. @@ -194,36 +170,13 @@ self.put(chr(lng)) self.put(x) - # HACK!ing a bit to loose some recursion depth and gain some speed. - # XXX it would be nicer to have a clean interface for this. - # remove this hack when we have optimization - # YYY we can drop the chain of mm dispatchers and save code if a method - # does not use NotImplemented at all. - def _get_mm_marshal(self, w_obj): - mm = getattr(w_obj, '__mm_marshal_w') - mm_func = mm.im_func - name = mm_func.func_code.co_names[0] - assert name.startswith('marshal_w_') - return mm_func.func_globals[name] - def put_w_obj(self, w_obj): - self.nesting += 2 - do_nested = self.nesting < nesting_limit - if CPYTHON_COMPATIBLE: - self.cpy_nesting += 1 - do_nested = do_nested and self.cpy_nesting < MAX_MARSHAL_DEPTH - if do_nested: - if DONT_USE_MM_HACK: - self.nesting += 2 - self.space.marshal_w(w_obj, self) - self.nesting -= 2 - else: - self._get_mm_marshal(w_obj)(self.space, w_obj, self) + self.nesting += 1 + if self.nesting < MAX_MARSHAL_DEPTH: + self.space.marshal_w(w_obj, self) else: - self._run_stackless(w_obj) - self.nesting -= 2 - if CPYTHON_COMPATIBLE: - self.cpy_nesting -= 1 + self._overflow() + self.nesting -= 1 # this function is inlined below def put_list_w(self, list_w, lng): @@ -236,38 +189,20 @@ self.nesting -= 1 def put_list_w(self, list_w, lng): - if DONT_USE_MM_HACK: - nest = 4 - marshal_w = self.space.marshal_w - else: - nest = 2 - # inlined version, two stack levels, only, with the hack! - self.nesting += nest + self.nesting += 1 self.put_int(lng) idx = 0 space = self.space - do_nested = self.nesting < nesting_limit - if CPYTHON_COMPATIBLE: - self.cpy_nesting += 1 - do_nested = do_nested and self.cpy_nesting < MAX_MARSHAL_DEPTH - if do_nested: + if self.nesting < MAX_MARSHAL_DEPTH: while idx < lng: w_obj = list_w[idx] - if DONT_USE_MM_HACK: - marshal_w(w_obj, self) - else: - self._get_mm_marshal(w_obj)(space, w_obj, self) + self.space.marshal_w(w_obj, self) idx += 1 else: - while idx < lng: - w_obj = list_w[idx] - self._run_stackless(w_obj) - idx += 1 - self.nesting -= nest - if CPYTHON_COMPATIBLE: - self.cpy_nesting -= 1 + self._overflow() + self.nesting -= 1 - def _run_stackless(self, w_obj): + def _overflow(self): self.raise_exc('object too deeply nested to marshal') @@ -337,7 +272,7 @@ x >>= 8 d = chr(x & 0xff) pos = self.bufpos - newpos = pos +4 + newpos = pos + 4 if len(self.buflis) < newpos: self.buflis = self.buflis + self.buflis self.buflis[pos] = a @@ -377,9 +312,7 @@ def __init__(self, space, reader): self.space = space self.reader = reader - # account for the applevel that we will call by one more. - self.nesting = ((space.getexecutioncontext().framestack.depth() + 1) - * APPLEVEL_STACK_COST) + self.nesting = 0 self.stringtable_w = [] def get(self, n): @@ -464,8 +397,8 @@ return res_w def get_w_obj(self, allow_null): - self.nesting += 2 - if self.nesting < nesting_limit: + self.nesting += 1 + if self.nesting < MAX_MARSHAL_DEPTH: tc = self.get1() w_ret = self._dispatch[ord(tc)](self.space, self, tc) if w_ret is None and not allow_null: @@ -473,19 +406,19 @@ raise OperationError(space.w_TypeError, space.wrap( 'NULL object in marshal data')) else: - w_ret = self._run_stackless() - self.nesting -= 2 + self._overflow() + self.nesting -= 1 return w_ret # inlined version to save a nesting level def get_list_w(self): - self.nesting += 2 + self.nesting += 1 lng = self.get_lng() res_w = [None] * lng idx = 0 space = self.space w_ret = space.w_None # something not None - if self.nesting < nesting_limit: + if self.nesting < MAX_MARSHAL_DEPTH: while idx < lng: tc = self.get1() w_ret = self._dispatch[ord(tc)](space, self, tc) @@ -494,19 +427,14 @@ res_w[idx] = w_ret idx += 1 else: - while idx < lng: - w_ret = self._run_stackless() - if w_ret is None: - break - res_w[idx] = w_ret - idx += 1 + self._overflow() if w_ret is None: raise OperationError(space.w_TypeError, space.wrap( 'NULL object in marshal data')) - self.nesting -= 2 + self.nesting -= 1 return res_w - def _run_stackless(self): + def _overflow(self): self.raise_exc('object too deeply nested to unmarshal') Modified: pypy/dist/pypy/module/marshal/test/test_marshalimpl.py ============================================================================== --- pypy/dist/pypy/module/marshal/test/test_marshalimpl.py (original) +++ pypy/dist/pypy/module/marshal/test/test_marshalimpl.py Sun Aug 28 18:16:57 2005 @@ -2,31 +2,6 @@ from pypy.interpreter.error import OperationError import sys -class TestInternalStuff: - def test_nesting(self): - space = self.space - app_cost = interp_marshal.APPLEVEL_STACK_COST - curdepth = space.getexecutioncontext().framestack.depth() - for do_hack in (False, True): - interp_marshal.DONT_USE_MM_HACK = not do_hack - if not do_hack: - interp_cost = 4 - else: - interp_cost = 2 - stacklimit = interp_marshal.nesting_limit - (curdepth + 1) * app_cost - interp_marshal.TEST_CONST - w_tup = space.newtuple([]) - tupdepth = 1 - for i in range(0, stacklimit - interp_cost-1, interp_cost): - w_tup = space.newtuple([w_tup]) - tupdepth += 1 - w_good = w_tup - s = interp_marshal.dumps(space, w_good, space.wrap(1)) - interp_marshal.loads(space, s) - w_bad = space.newtuple([w_tup]) - raises(OperationError, interp_marshal.dumps, space, w_bad, space.wrap(1)) - print 'max sys depth = %d, mm_hack = %r, marshal limit = %d' % ( - sys.getrecursionlimit(), do_hack, tupdepth) - class AppTestMarshalMore: From tismer at codespeak.net Sun Aug 28 18:28:31 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 28 Aug 2005 18:28:31 +0200 (CEST) Subject: [pypy-svn] r17015 - in pypy/dist/pypy/lib: _fakecompiler _stablecompiler Message-ID: <20050828162831.6EAC827B5A@code1.codespeak.net> Author: tismer Date: Sun Aug 28 18:28:30 2005 New Revision: 17015 Modified: pypy/dist/pypy/lib/_fakecompiler/fakecompiler.py pypy/dist/pypy/lib/_stablecompiler/apphook.py Log: reverted the _fakecompiler change to usemarshal, again. This has two reasons: - marshal is now always using the full depth of CPython's 5000 - using eval for such deep tuples gets even worse - I want the interface file be always a marshal file, just for the case that wemight not have been able to run Python at all. Then the file is still valid, telling this by the done flag being false. Modified: pypy/dist/pypy/lib/_fakecompiler/fakecompiler.py ============================================================================== --- pypy/dist/pypy/lib/_fakecompiler/fakecompiler.py (original) +++ pypy/dist/pypy/lib/_fakecompiler/fakecompiler.py Sun Aug 28 18:28:30 2005 @@ -16,8 +16,7 @@ if __name__ == '__main__': s = file(DUMPFILE, "rb").read() - #tup = marshal.loads(s) - tup = eval(s) + tup = marshal.loads(s) tuples_or_src, filename, mode, done, flag_names = tup try: code = reallycompile(tuples_or_src, filename, mode, flag_names) Modified: pypy/dist/pypy/lib/_stablecompiler/apphook.py ============================================================================== --- pypy/dist/pypy/lib/_stablecompiler/apphook.py (original) +++ pypy/dist/pypy/lib/_stablecompiler/apphook.py Sun Aug 28 18:28:30 2005 @@ -29,8 +29,11 @@ def fakeapplevelcompile(tuples_or_src, filename, mode, flag_names): import os, marshal done = False - #data = marshal.dumps( (tuples_or_src, filename, mode, done, flag_names)) - data = repr( (tuples_or_src, filename, mode, done, flag_names)) + try: + data = marshal.dumps( (tuples_or_src, filename, mode, done, flag_names)) + except ValueError: + raise ValueError, ("ST tuple too deeply nested for fake compiling!" + " Please use the fakecompletely option") f = file(DUMPFILE, "wb") f.write(data) f.close() From arigo at codespeak.net Sun Aug 28 18:47:39 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 18:47:39 +0200 (CEST) Subject: [pypy-svn] r17016 - in pypy/dist/pypy/translator: c/test llvm Message-ID: <20050828164739.EC8D027B5D@code1.codespeak.net> Author: arigo Date: Sun Aug 28 18:47:39 2005 New Revision: 17016 Modified: pypy/dist/pypy/translator/c/test/test_boehm.py pypy/dist/pypy/translator/llvm/genllvm.py Log: Manual merging of two changes from the release/0.7.x branch (r16833:16842): * (tismer) fix tabs * (pedronis) skip boehm test for now Modified: pypy/dist/pypy/translator/c/test/test_boehm.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_boehm.py (original) +++ pypy/dist/pypy/translator/c/test/test_boehm.py Sun Aug 28 18:47:39 2005 @@ -50,6 +50,7 @@ def test_boehm(): import py + py.test.skip("boehm test is fragile wrt. the number of dynamically loaded libs") from pypy.translator.tool import cbuild if not cbuild.check_boehm_presence(): py.test.skip("no boehm gc on this machine") Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Sun Aug 28 18:47:39 2005 @@ -66,8 +66,8 @@ returntype, s = line.split(' ', 1) funcname , s = s.split('(', 1) funcnames[funcname] = True - if line.find("internal") == -1: - line = '%s %s %s' % ("", DEFAULT_CCONV, line,) + if line.find("internal") == -1: + line = '%s %s %s' % ("", DEFAULT_CCONV, line,) ll_lines.append(line) # patch calls to function that we just declared fastcc @@ -333,7 +333,7 @@ for f in "raisePyExc_IOError raisePyExc_ValueError "\ "raisePyExc_OverflowError raisePyExc_ZeroDivisionError "\ "prepare_ZeroDivisionError prepare_OverflowError prepare_ValueError "\ - "RPyString_FromString RPyString_AsString RPyString_Size".split(): + "RPyString_FromString RPyString_AsString RPyString_Size".split(): extfuncnode.ExternalFuncNode.used_external_functions["%" + f] = True if self.debug: print 'gen_llvm_source used_external_functions) ' + time.ctime() From arigo at codespeak.net Sun Aug 28 18:57:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 18:57:08 +0200 (CEST) Subject: [pypy-svn] r17017 - in pypy/dist: . pypy/bin pypy/doc pypy/interpreter/stablecompiler pypy/lib/_stablecompiler pypy/module/_codecs pypy/module/_sre pypy/module/_sre/test pypy/tool pypy/tool/pytest pypy/tool/pytest/test pypy/tool/test pypy/translator pypy/translator/goal Message-ID: <20050828165708.4B5F827B5D@code1.codespeak.net> Author: arigo Date: Sun Aug 28 18:57:07 2005 New Revision: 17017 Removed: pypy/dist/README pypy/dist/pypy/bin/translator.py pypy/dist/pypy/doc/architecture.txt pypy/dist/pypy/doc/coding-guide.txt pypy/dist/pypy/doc/faq.txt pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/release-0.7.0.txt pypy/dist/pypy/doc/translation.txt pypy/dist/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/lib/_stablecompiler/transformer.py pypy/dist/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_interp_sre.py pypy/dist/pypy/tool/makerelease.py pypy/dist/pypy/tool/pytest/genreportdata.py pypy/dist/pypy/tool/pytest/htmlreport.py pypy/dist/pypy/tool/pytest/test/test_new_count.py pypy/dist/pypy/tool/test/test_getdocstrings.py pypy/dist/pypy/translator/goal/run_pypy-llvm.sh pypy/dist/pypy/translator/goal/targetpypystandalone.py pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/translator.py Log: Merging release/0.7.x, step 1 From arigo at codespeak.net Sun Aug 28 18:58:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 18:58:12 +0200 (CEST) Subject: [pypy-svn] r17018 - in pypy/dist: . pypy/bin pypy/doc pypy/interpreter/stablecompiler pypy/lib/_stablecompiler pypy/module/_codecs pypy/module/_sre pypy/module/_sre/test pypy/tool pypy/tool/pytest pypy/tool/pytest/test pypy/tool/test pypy/translator pypy/translator/goal Message-ID: <20050828165812.9B76F27B5F@code1.codespeak.net> Author: arigo Date: Sun Aug 28 18:58:11 2005 New Revision: 17018 Added: pypy/dist/README - copied unchanged from r17014, pypy/release/0.7.x/README pypy/dist/pypy/bin/translator.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/bin/translator.py pypy/dist/pypy/doc/architecture.txt - copied unchanged from r17014, pypy/release/0.7.x/pypy/doc/architecture.txt pypy/dist/pypy/doc/coding-guide.txt - copied unchanged from r17014, pypy/release/0.7.x/pypy/doc/coding-guide.txt pypy/dist/pypy/doc/faq.txt - copied unchanged from r17014, pypy/release/0.7.x/pypy/doc/faq.txt pypy/dist/pypy/doc/getting-started.txt - copied unchanged from r17014, pypy/release/0.7.x/pypy/doc/getting-started.txt pypy/dist/pypy/doc/release-0.7.0.txt - copied unchanged from r17014, pypy/release/0.7.x/pypy/doc/release-0.7.0.txt pypy/dist/pypy/doc/translation.txt - copied unchanged from r17014, pypy/release/0.7.x/pypy/doc/translation.txt pypy/dist/pypy/interpreter/stablecompiler/transformer.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/interpreter/stablecompiler/transformer.py pypy/dist/pypy/lib/_stablecompiler/transformer.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/lib/_stablecompiler/transformer.py pypy/dist/pypy/module/_codecs/app_codecs.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/module/_codecs/app_codecs.py pypy/dist/pypy/module/_sre/interp_sre.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/module/_sre/interp_sre.py pypy/dist/pypy/module/_sre/test/test_interp_sre.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/module/_sre/test/test_interp_sre.py pypy/dist/pypy/tool/makerelease.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/tool/makerelease.py pypy/dist/pypy/tool/pytest/genreportdata.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/tool/pytest/genreportdata.py pypy/dist/pypy/tool/pytest/htmlreport.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/tool/pytest/htmlreport.py pypy/dist/pypy/tool/pytest/test/test_new_count.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/tool/pytest/test/test_new_count.py pypy/dist/pypy/tool/test/test_getdocstrings.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/tool/test/test_getdocstrings.py pypy/dist/pypy/translator/goal/run_pypy-llvm.sh - copied unchanged from r17014, pypy/release/0.7.x/pypy/translator/goal/run_pypy-llvm.sh pypy/dist/pypy/translator/goal/targetpypystandalone.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/translator/goal/targetpypystandalone.py pypy/dist/pypy/translator/goal/translate_pypy.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/translator.py - copied unchanged from r17014, pypy/release/0.7.x/pypy/translator/translator.py Log: Merging release/0.7.x, step 2: all files modified in the branch are now copied into the trunk. From arigo at codespeak.net Sun Aug 28 19:26:35 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 19:26:35 +0200 (CEST) Subject: [pypy-svn] r17020 - pypy/dist/pypy/doc Message-ID: <20050828172635.B316527B66@code1.codespeak.net> Author: arigo Date: Sun Aug 28 19:26:34 2005 New Revision: 17020 Modified: pypy/dist/pypy/doc/news.txt Log: Announce the 0.7.0 release on the home page's news. Remove the oldest news item, which was about release 0.6. Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Sun Aug 28 19:26:34 2005 @@ -9,6 +9,20 @@ .. _Python: http://www.python.org/doc/current/ref/ref.html .. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html#mission-statement +PyPy release 0.7.0 +=================== + +The first implementation of Python in Python is now also the second +implementation of Python in C :-) + +See the `release announcement`_ for further details about the release and +the `getting started`_ document for instructions about downloading it and +trying it out. We also have the beginning of a FAQ_. *(08/28/2005)* + +.. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html +.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html +.. _FAQ: http://codespeak.net/pypy/dist/pypy/doc/faq.html + Ongoing: PyPy Sprint in Heidelberg 22nd-29th August 2005 ========================================================== @@ -70,17 +84,3 @@ .. _`translation`: http://codespeak.net/pypy/dist/pypy/doc/translation.html .. _`sprint announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-announcement.html .. _`list of people coming`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-people.html - -First PyPy release! -=================== - -We are happy to announce the first public release of PyPy after two years of -spare-time and half a year of EU funded development. The 0.6 release is -a preview release, concentrating on CPython compatibility, good documentation -and nice starting points into the PyPy code base. We invite you to head -over to the `getting started`_ document or read more in the -`release announcement`_. *(05/20/2005)* - -.. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.6.html -.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html - From pedronis at codespeak.net Sun Aug 28 19:27:07 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 28 Aug 2005 19:27:07 +0200 (CEST) Subject: [pypy-svn] r17021 - pypy/dist/pypy/translator/c Message-ID: <20050828172707.B9CFB27B70@code1.codespeak.net> Author: pedronis Date: Sun Aug 28 19:27:06 2005 New Revision: 17021 Modified: pypy/dist/pypy/translator/c/gc.py Log: oops, try to improve things a bit Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Sun Aug 28 19:27:06 2005 @@ -303,7 +303,7 @@ if arraydefnode.gcinfo: gcinfo = arraydefnode.gcinfo if gcinfo.finalizer: - yield 'void %s(GC_PTR obj, GC_PTR ignore) {' % (gcinfo.finalizer, arraydefnode.name) + yield 'void %s(GC_PTR obj, GC_PTR ignore) {' % (gcinfo.finalizer) yield '\tstruct %s *a = (struct %s *)obj;' % (arraydefnode.name, arraydefnode.name) for line in self.deallocator_lines(arraydefnode, '(*a)'): yield '\t' + line @@ -319,7 +319,7 @@ if structdefnode.gcinfo: gcinfo = structdefnode.gcinfo if gcinfo.finalizer: - yield 'void %s(GC_PTR obj, GC_PTR ignore) {' % (gcinfo.finalizer, structdefnode.name) + yield 'void %s(GC_PTR obj, GC_PTR ignore) {' % gcinfo.finalizer yield '\tstruct %s *p = (struct %s *)obj;' % (structdefnode.name, structdefnode.name) for line in self.deallocator_lines(structdefnode, '(*p)'): yield '\t' + line From arigo at codespeak.net Sun Aug 28 19:34:00 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 28 Aug 2005 19:34:00 +0200 (CEST) Subject: [pypy-svn] r17022 - pypy/release/0.7.x/pypy/doc Message-ID: <20050828173400.6AE0127B73@code1.codespeak.net> Author: arigo Date: Sun Aug 28 19:34:00 2005 New Revision: 17022 Modified: pypy/release/0.7.x/pypy/doc/news.txt Log: Merged from the trunk. Modified: pypy/release/0.7.x/pypy/doc/news.txt ============================================================================== --- pypy/release/0.7.x/pypy/doc/news.txt (original) +++ pypy/release/0.7.x/pypy/doc/news.txt Sun Aug 28 19:34:00 2005 @@ -9,6 +9,20 @@ .. _Python: http://www.python.org/doc/current/ref/ref.html .. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html#mission-statement +PyPy release 0.7.0 +=================== + +The first implementation of Python in Python is now also the second +implementation of Python in C :-) + +See the `release announcement`_ for further details about the release and +the `getting started`_ document for instructions about downloading it and +trying it out. We also have the beginning of a FAQ_. *(08/28/2005)* + +.. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html +.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html +.. _FAQ: http://codespeak.net/pypy/dist/pypy/doc/faq.html + Ongoing: PyPy Sprint in Heidelberg 22nd-29th August 2005 ========================================================== @@ -70,17 +84,3 @@ .. _`translation`: http://codespeak.net/pypy/dist/pypy/doc/translation.html .. _`sprint announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-announcement.html .. _`list of people coming`: http://codespeak.net/pypy/extradoc/sprintinfo/EP2005-people.html - -First PyPy release! -=================== - -We are happy to announce the first public release of PyPy after two years of -spare-time and half a year of EU funded development. The 0.6 release is -a preview release, concentrating on CPython compatibility, good documentation -and nice starting points into the PyPy code base. We invite you to head -over to the `getting started`_ document or read more in the -`release announcement`_. *(05/20/2005)* - -.. _`release announcement`: http://codespeak.net/pypy/dist/pypy/doc/release-0.6.html -.. _`getting started`: http://codespeak.net/pypy/dist/pypy/doc/getting-started.html - From ericvrp at codespeak.net Mon Aug 29 09:57:49 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 29 Aug 2005 09:57:49 +0200 (CEST) Subject: [pypy-svn] r17028 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20050829075749.5A5BB27B4D@code1.codespeak.net> Author: ericvrp Date: Mon Aug 29 09:57:48 2005 New Revision: 17028 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_bufio.py (props changed) pypy/dist/lib-python/modified-2.4.1/test/test_format.py (props changed) Log: fixeol From pedronis at codespeak.net Mon Aug 29 11:37:56 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 29 Aug 2005 11:37:56 +0200 (CEST) Subject: [pypy-svn] r17032 - pypy/dist/pypy/module/marshal Message-ID: <20050829093756.B0C9127B49@code1.codespeak.net> Author: pedronis Date: Mon Aug 29 11:37:55 2005 New Revision: 17032 Modified: pypy/dist/pypy/module/marshal/interp_marshal.py Log: fix reference before assigment problem Modified: pypy/dist/pypy/module/marshal/interp_marshal.py ============================================================================== --- pypy/dist/pypy/module/marshal/interp_marshal.py (original) +++ pypy/dist/pypy/module/marshal/interp_marshal.py Mon Aug 29 11:37:55 2005 @@ -398,11 +398,12 @@ def get_w_obj(self, allow_null): self.nesting += 1 + space = self.space + w_ret = space.w_None # something not None if self.nesting < MAX_MARSHAL_DEPTH: tc = self.get1() - w_ret = self._dispatch[ord(tc)](self.space, self, tc) + w_ret = self._dispatch[ord(tc)](space, self, tc) if w_ret is None and not allow_null: - space = self.space raise OperationError(space.w_TypeError, space.wrap( 'NULL object in marshal data')) else: From ericvrp at codespeak.net Mon Aug 29 14:30:51 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 29 Aug 2005 14:30:51 +0200 (CEST) Subject: [pypy-svn] r17037 - pypy/dist/pypy/translator/llvm/test Message-ID: <20050829123051.58AD627B4D@code1.codespeak.net> Author: ericvrp Date: Mon Aug 29 14:30:50 2005 New Revision: 17037 Modified: pypy/dist/pypy/translator/llvm/test/runtest.py pypy/dist/pypy/translator/llvm/test/test_lltype.py Log: added test for minimum llvm version (1.6(cvs) at the moment) Modified: pypy/dist/pypy/translator/llvm/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/runtest.py (original) +++ pypy/dist/pypy/translator/llvm/test/runtest.py Mon Aug 29 14:30:50 2005 @@ -2,6 +2,7 @@ from pypy.translator.llvm.genllvm import compile_module optimize_tests = False +MINIMUM_LLVM_VERSION = 1.6 def llvm_is_on_path(): try: @@ -10,16 +11,31 @@ return False return True +def llvm_version(): + import os + v = os.popen('llvm-as -version 2>&1').readline() + v = ''.join([c for c in v if c.isdigit()]) + v = int(v) / 10.0 + return v + def compile_function(function, annotation, **kwds): if not llvm_is_on_path(): py.test.skip("llvm not found") - + + v = llvm_version() + if v < MINIMUM_LLVM_VERSION: + py.test.skip("llvm version not up-to-date (found %.1f, should be >= %.1f)" % (v, MINIMUM_LLVM_VERSION)) + mod = compile_module(function, annotation, optimize=optimize_tests, **kwds) return getattr(mod, 'pypy_' + function.func_name + "_wrapper") def compile_module_function(function, annotation, **kwds): if not llvm_is_on_path(): py.test.skip("llvm not found") + + v, minimum = llvm_version(), 1.6 + if v < minimum: + py.test.skip("llvm version not up-to-date (found %.1f, should be >= %.1f)" % (v, minimum)) mod = compile_module(function, annotation, **kwds) f = getattr(mod, 'pypy_' + function.func_name + "_wrapper") Modified: pypy/dist/pypy/translator/llvm/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_lltype.py Mon Aug 29 14:30:50 2005 @@ -236,6 +236,5 @@ res += floats.f4 > 1e200 res += floats.f5 == nan return res - f = compile_function(floats_fn, []) assert f() == floats_fn() From ale at codespeak.net Mon Aug 29 16:29:59 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 29 Aug 2005 16:29:59 +0200 (CEST) Subject: [pypy-svn] r17039 - pypy/dist/pypy/module/_codecs/test Message-ID: <20050829142959.B303027B5E@code1.codespeak.net> Author: ale Date: Mon Aug 29 16:29:58 2005 New Revision: 17039 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: Added test for named unicode characters Cleaned tests for partial evaluation of utf-8 and utf-16 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Mon Aug 29 16:29:58 2005 @@ -1,7 +1,56 @@ import autopath +from pypy.objspace.std import StdObjSpace class AppTestCodecs: + def test_bigU_codecs(self): + import sys + oldmaxunicode = sys.maxunicode + if sys.maxunicode <= 0xffff: + sys.maxunicode = 0xffffffff + u = u'\U00010001\U00020002\U00030003\U00040004\U00050005' + for encoding in ('utf-8', 'utf-16', 'utf-16-le', 'utf-16-be', + 'raw_unicode_escape', + 'unicode_escape', 'unicode_internal'): + assert unicode(u.encode(encoding),encoding) == u + sys.maxunicode = oldmaxunicode + + def test_ucs4(self): + import sys + oldmaxunicode = sys.maxunicode + if sys.maxunicode <= 0xffff: + sys.maxunicode = 0xffffffff + x = u'\U00100000' + y = x.encode("raw-unicode-escape").decode("raw-unicode-escape") + assert x == y + sys.maxunicode = oldmaxunicode + + def test_named_unicode(self): + assert unicode('\\N{SPACE}','unicode-escape') == u" " + raises( UnicodeDecodeError, unicode,'\\N{SPACE','unicode-escape') + raises( UnicodeDecodeError, unicode,'\\NSPACE}','unicode-escape') + raises( UnicodeDecodeError, unicode,'\\NSPACE','unicode-escape') + raises( UnicodeDecodeError, unicode,'\\N','unicode-escape') + raises( UnicodeDecodeError, unicode,'\\N{SpaCE}','unicode-escape') + assert unicode('\\N{SPACE}\\N{SPACE}','unicode-escape') == u" " + assert unicode('\\N{SPACE}a\\N{SPACE}','unicode-escape') == u" a " + + def test_insecure_pickle(self): + import pickle + insecure = ["abc", "2 + 2", # not quoted + #"'abc' + 'def'", # not a single quoted string + "'abc", # quote is not closed + "'abc\"", # open quote and close quote don't match + "'abc' ?", # junk after close quote + "'\\'", # trailing backslash + # some tests of the quoting rules + #"'abc\"\''", + #"'\\\\a\'\'\'\\\'\\\\\''", + ] + for s in insecure: + buf = "S" + s + "\012p0\012." + raises (ValueError, pickle.loads, buf) + def test_unicodedecodeerror(self): assert str(UnicodeDecodeError( "ascii", "g\xfcrk", 1, 2, "ouch")) == "'ascii' codec can't decode byte 0xfc in position 1: ouch" @@ -53,120 +102,39 @@ raises (ValueError, test.decode,'string-escape') - def test_insecure_pickle(self): - import pickle - insecure = ["abc", "2 + 2", # not quoted - #"'abc' + 'def'", # not a single quoted string - "'abc", # quote is not closed - "'abc\"", # open quote and close quote don't match - "'abc' ?", # junk after close quote - "'\\'", # trailing backslash - # some tests of the quoting rules - #"'abc\"\''", - #"'\\\\a\'\'\'\\\'\\\\\''", - ] - for s in insecure: - buf = "S" + s + "\012p0\012." - raises (ValueError, pickle.loads, buf) +class AppTestPartialEvaluation: def test_partial_utf8(self): - class Queue(object): - """ - queue: write bytes at one end, read bytes from the other end - """ - def __init__(self): - self._buffer = "" - - def write(self, chars): - self._buffer += chars - - def read(self, size=-1): - if size<0: - s = self._buffer - self._buffer = "" - return s - else: - s = self._buffer[:size] - self._buffer = self._buffer[size:] - return s - def check_partial(encoding, input, partialresults): - import codecs - - # get a StreamReader for the encoding and feed the bytestring version - # of input to the reader byte by byte. Read every available from - # the StreamReader and check that the results equal the appropriate - # entries from partialresults. - q = Queue() - r = codecs.getreader(encoding)(q) - result = u"" - for (c, partialresult) in zip(input.encode(encoding), partialresults): - q.write(c) - result += r.read() - assert result == partialresult - # check that there's nothing left in the buffers - assert r.read() == u"" - assert r.bytebuffer == "" - assert r.charbuffer == u"" - encoding = 'utf-8' - check_partial(encoding, + import _codecs + encoding = 'utf-8' + check_partial = [ + u"\x00", + u"\x00", + u"\x00\xff", + u"\x00\xff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800", + u"\x00\xff\u07ff\u0800", u"\x00\xff\u07ff\u0800\uffff", - [ - u"\x00", - u"\x00", - u"\x00\xff", - u"\x00\xff", - u"\x00\xff\u07ff", - u"\x00\xff\u07ff", - u"\x00\xff\u07ff", - u"\x00\xff\u07ff\u0800", - u"\x00\xff\u07ff\u0800", - u"\x00\xff\u07ff\u0800", - u"\x00\xff\u07ff\u0800\uffff", - ] - ) + ] + + buffer = '' + result = u"" + for (c, partialresult) in zip(u"\x00\xff\u07ff\u0800\uffff".encode(encoding), check_partial): + buffer += c + res = _codecs.utf_8_decode(buffer,'strict',False) + if res[1] >0 : + buffer = '' + result += res[0] + assert result == partialresult def test_partial_utf16(self): - class Queue(object): - """ - queue: write bytes at one end, read bytes from the other end - """ - def __init__(self): - self._buffer = "" - - def write(self, chars): - self._buffer += chars - - def read(self, size=-1): - if size<0: - s = self._buffer - self._buffer = "" - return s - else: - s = self._buffer[:size] - self._buffer = self._buffer[size:] - return s - def check_partial(encoding, input, partialresults): - import codecs - - # get a StreamReader for the encoding and feed the bytestring version - # of input to the reader byte by byte. Read every available from - # the StreamReader and check that the results equal the appropriate - # entries from partialresults. - q = Queue() - r = codecs.getreader(encoding)(q) - result = u"" - for (c, partialresult) in zip(input.encode(encoding), partialresults): - q.write(c) - result += r.read() - assert result == partialresult - # check that there's nothing left in the buffers - assert r.read() == u"" - assert r.bytebuffer == "" - assert r.charbuffer == u"" + import _codecs encoding = 'utf-16' - check_partial(encoding, - u"\x00\xff\u0100\uffff", - [ + check_partial = [ u"", # first byte of BOM read u"", # second byte of BOM read => byteorder known u"", @@ -177,8 +145,19 @@ u"\x00\xff\u0100", u"\x00\xff\u0100", u"\x00\xff\u0100\uffff", - ]) + ] + buffer = '' + result = u"" + for (c, partialresult) in zip(u"\x00\xff\u0100\uffff".encode(encoding), check_partial): + buffer += c + res = _codecs.utf_16_decode(buffer,'strict',False) + if res[1] >0 : + buffer = '' + result += res[0] + assert result == partialresult + def test_bug1098990_a(self): + import codecs, StringIO self.encoding = 'utf-8' s1 = u"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\r\n" From cfbolz at codespeak.net Mon Aug 29 16:59:50 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 16:59:50 +0200 (CEST) Subject: [pypy-svn] r17040 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050829145950.855BD27B66@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 16:59:47 2005 New Revision: 17040 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: somewhat of an intermediate checkin: I refactored the GCs in a way that makes them hopefully be annotatable soon. Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Mon Aug 29 16:59:47 2005 @@ -14,22 +14,14 @@ types.BuiltinFunctionType) class LLTypeConverter(object): - def __init__(self, address, gc=None): + def __init__(self, address, gc=None, qt=None): self.type_to_typeid = {} self.types = [] self.converted = {} self.curraddress = address self.constantroots = [] self.gc = gc - - def get_typeid(self, TYPE): - if TYPE not in self.type_to_typeid: - index = len(self.types) - self.type_to_typeid[TYPE] = index - self.types.append(TYPE) - return index - typeid = self.type_to_typeid[TYPE] - return typeid + self.query_types = qt def convert(self, val_or_ptr, inline_to_ptr=None): TYPE = lltype.typeOf(val_or_ptr) @@ -63,12 +55,12 @@ ptr = inline_to_ptr else: startaddr = self.curraddress - if self.gc is not None: - self.gc.init_gc_object(startaddr, self.get_typeid(TYPE)) - startaddr += self.gc.size_gc_header() self.curraddress += size if self.gc is not None: - self.curraddress += self.gc.size_gc_header() + typeid = self.query_types.get_typeid(TYPE) + self.gc.init_gc_object(startaddr, typeid) + startaddr += self.gc.size_gc_header(typeid) + self.curraddress += self.gc.size_gc_header(typeid) ptr = init_object_on_address(startaddr, TYPE, arraylength) self.constantroots.append(ptr) self.converted[_array] = ptr @@ -103,12 +95,12 @@ ptr = inline_to_ptr else: startaddr = self.curraddress - if self.gc is not None: - self.gc.init_gc_object(startaddr, self.get_typeid(TYPE)) - startaddr += self.gc.size_gc_header() self.curraddress += size if self.gc is not None: - self.curraddress += self.gc.size_gc_header() + typeid = self.query_types.get_typeid(TYPE) + self.gc.init_gc_object(startaddr, typeid) + startaddr += self.gc.size_gc_header(typeid) + self.curraddress += self.gc.size_gc_header(typeid) ptr = init_object_on_address(startaddr, TYPE, inlinedarraylength) self.constantroots.append(ptr) self.converted[_struct] = ptr @@ -134,12 +126,13 @@ lladdress.get_address_of_object(_obj)) class FlowGraphConstantConverter(object): - def __init__(self, flowgraphs, gc=None): + def __init__(self, flowgraphs, gc=None, qt=None): self.flowgraphs = flowgraphs self.memory = lladdress.NULL self.cvter = None self.total_size = 0 self.gc = gc + self.query_types = qt def collect_constants_and_types(self): constants = {} @@ -192,7 +185,8 @@ length = len(cand.items) total_size += sizeof(cand._TYPE, length) if self.gc is not None: - total_size += self.gc.size_gc_header() + typeid = self.query_types.get_typeid(cand._TYPE) + total_size += self.gc.size_gc_header(typeid) for item in cand.items: candidates.append(item) elif isinstance(cand, lltype._struct): @@ -211,7 +205,8 @@ else: total_size += sizeof(TYPE) if self.gc is not None: - total_size += self.gc.size_gc_header() + typeid = self.query_types.get_typeid(TYPE) + total_size += self.gc.size_gc_header(typeid) for name in TYPE._flds: candidates.append(getattr(cand, name)) elif isinstance(cand, lltype._opaque): @@ -226,7 +221,7 @@ def convert_constants(self): self.memory = lladdress.raw_malloc(self.total_size) - self.cvter = LLTypeConverter(self.memory, self.gc) + self.cvter = LLTypeConverter(self.memory, self.gc, self.query_types) for constant in self.constants.iterkeys(): if isinstance(constant.value, lltype.LowLevelType): self.constants[constant] = constant.value @@ -256,16 +251,16 @@ def create_type_ids(self): for TYPE in self.types: - print TYPE if isinstance(TYPE, (lltype.Array, lltype.Struct)): #assign a typeid - self.cvter.get_typeid(TYPE) + self.query_types.get_typeid(TYPE) elif isinstance(TYPE, lltype.Ptr): - self.cvter.get_typeid(TYPE.TO) + self.query_types.get_typeid(TYPE.TO) def convert(self): self.collect_constants_and_types() self.calculate_size() self.convert_constants() self.patch_graphs() - self.create_type_ids() + if self.query_types is not None: + self.create_type_ids() Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Mon Aug 29 16:59:47 2005 @@ -10,24 +10,50 @@ class GCError(Exception): pass +class GCBase(object): + _alloc_flavor_ = "raw" + + def set_query_functions(self, is_varsize, offsets_to_gc_pointers, + fixed_size, varsize_item_sizes, + varsize_offset_to_variable_part, + varsize_offset_to_length, + varsize_offsets_to_gcpointers_in_var_part): + self.is_varsize = is_varsize + self.offsets_to_gc_pointers = offsets_to_gc_pointers + self.fixed_size = fixed_size + self.varsize_item_sizes = varsize_item_sizes + self.varsize_offset_to_variable_part = varsize_offset_to_variable_part + self.varsize_offset_to_length = varsize_offset_to_length + self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part + -class MarkSweepGC(object): +class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" - def __init__(self, objectmodel, start_heap_size): + def __init__(self, start_heap_size, get_roots, is_varsize, + offsets_to_gc_pointers, fixed_size, varsize_item_sizes, + varsize_offset_to_variable_part, varsize_offset_to_length, + varsize_offsets_to_gcpointers_in_var_part): self.bytes_malloced = 0 self.heap_size = start_heap_size #need to maintain a list of malloced objects, since we used the systems #allocator and can't walk the heap self.malloced_objects = AddressLinkedList() - self.objectmodel = objectmodel + self.is_varsize = is_varsize + self.offsets_to_gc_pointers = offsets_to_gc_pointers + self.fixed_size = fixed_size + self.varsize_item_sizes = varsize_item_sizes + self.varsize_offset_to_variable_part = varsize_offset_to_variable_part + self.varsize_offset_to_length = varsize_offset_to_length + self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part + self.get_roots = get_roots def malloc(self, typeid, length=0): if self.bytes_malloced > self.heap_size: self.collect() - size = self.objectmodel.fixed_size(typeid) - if self.objectmodel.is_varsize(typeid): - size += length * self.objectmodel.varsize_item_sizes(typeid) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + size += length * self.varsize_item_sizes(typeid) size_gc_header = self.size_gc_header() result = raw_malloc(size + size_gc_header) print "mallocing %s, size %s at %s" % (typeid, size, result) @@ -39,7 +65,7 @@ def collect(self): print "collecting" self.bytes_malloced = 0 - roots = self.objectmodel.get_roots() + roots = self.get_roots() objects = AddressLinkedList() while 1: curr = roots.pop() @@ -61,16 +87,16 @@ if gc_info.signed[0] == 1: continue typeid = gc_info.signed[1] - offsets = self.objectmodel.offsets_to_gc_pointers(typeid) + offsets = self.offsets_to_gc_pointers(typeid) for i in range(len(offsets)): pointer = curr + offsets[i] objects.append(pointer.address[0]) - if self.objectmodel.is_varsize(typeid): - offset = self.objectmodel.varsize_offset_to_variable_part( + if self.is_varsize(typeid): + offset = self.varsize_offset_to_variable_part( typeid) - length = (curr + self.objectmodel.varsize_offset_to_length(typeid)).signed[0] - offsets = self.objectmodel.varsize_offsets_to_gcpointers_in_var_part(typeid) - itemlength = self.objectmodel.varsize_item_sizes(typeid) + length = (curr + self.varsize_offset_to_length(typeid)).signed[0] + offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid) + itemlength = self.varsize_item_sizes(typeid) curr += offset for i in range(length): item = curr + itemlength * i @@ -85,10 +111,10 @@ if curr == NULL: break typeid = curr.signed[1] - size = self.objectmodel.fixed_size(typeid) - if self.objectmodel.is_varsize(typeid): - length = (curr + self.size_gc_header() + self.objectmodel.varsize_offset_to_length(typeid)).signed[0] - size += length * self.objectmodel.varsize_item_sizes(typeid) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + length = (curr + self.size_gc_header() + self.varsize_offset_to_length(typeid)).signed[0] + size += length * self.varsize_item_sizes(typeid) if curr.signed[0] == 1: curr.signed[0] = 0 newmo.append(curr) @@ -102,7 +128,7 @@ if curr_heap_size > self.heap_size: self.heap_size = curr_heap_size - def size_gc_header(self): + def size_gc_header(self, typeid=0): return lltypesimulation.sizeof(lltype.Signed) * 2 def init_gc_object(self, addr, typeid): @@ -110,22 +136,32 @@ addr.signed[1] = typeid -class SemiSpaceGC(object): +class SemiSpaceGC(GCBase): _alloc_flavor_ = "raw" - def __init__(self, objectmodel, space_size): + def __init__(self, space_size, get_roots, is_varsize, + offsets_to_gc_pointers, fixed_size, varsize_item_sizes, + varsize_offset_to_variable_part, varsize_offset_to_length, + varsize_offsets_to_gcpointers_in_var_part): self.bytes_malloced = 0 self.space_size = space_size self.tospace = raw_malloc(space_size) self.top_of_space = self.tospace + space_size self.fromspace = raw_malloc(space_size) self.free = self.tospace - self.objectmodel = objectmodel + self.is_varsize = is_varsize + self.offsets_to_gc_pointers = offsets_to_gc_pointers + self.fixed_size = fixed_size + self.varsize_item_sizes = varsize_item_sizes + self.varsize_offset_to_variable_part = varsize_offset_to_variable_part + self.varsize_offset_to_length = varsize_offset_to_length + self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part + self.get_roots = get_roots def malloc(self, typeid, length=0): - size = self.objectmodel.fixed_size(typeid) - if self.objectmodel.is_varsize(typeid): - size += length * self.objectmodel.varsize_item_sizes(typeid) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + size += length * self.varsize_item_sizes(typeid) totalsize = size + self.size_gc_header() if self.free + totalsize > self.top_of_space: self.collect() @@ -143,7 +179,7 @@ print "collecting" self.fromspace, self.tospace = self.tospace, self.fromspace self.top_of_space = self.tospace + self.space_size - roots = self.objectmodel.get_roots() + roots = self.get_roots() scan = self.free = self.tospace while 1: root = roots.pop() @@ -174,7 +210,7 @@ return newobj def copy_non_managed_obj(self, obj): #umph, PBCs, not really copy - print "copying nonmanaged", obj, self.objectmodel.types[obj.signed[-1]] + print "copying nonmanaged", obj #we have to do the tracing here because PBCs are not moved to tospace self.trace_and_copy(obj) return obj @@ -183,17 +219,17 @@ gc_info = obj - self.size_gc_header() typeid = gc_info.signed[1] print "scanning", obj, typeid - offsets = self.objectmodel.offsets_to_gc_pointers(typeid) + offsets = self.offsets_to_gc_pointers(typeid) for i in range(len(offsets)): pointer = obj + offsets[i] if pointer.address[0] != NULL: pointer.address[0] = self.copy(pointer.address[0]) - if self.objectmodel.is_varsize(typeid): - offset = self.objectmodel.varsize_offset_to_variable_part( + if self.is_varsize(typeid): + offset = self.varsize_offset_to_variable_part( typeid) - length = (obj + self.objectmodel.varsize_offset_to_length(typeid)).signed[0] - offsets = self.objectmodel.varsize_offsets_to_gcpointers_in_var_part(typeid) - itemlength = self.objectmodel.varsize_item_sizes(typeid) + length = (obj + self.varsize_offset_to_length(typeid)).signed[0] + offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid) + itemlength = self.varsize_item_sizes(typeid) for i in range(length): item = obj + offset + itemlength * i for j in range(len(offsets)): @@ -214,15 +250,15 @@ def get_size(self, obj): typeid = (obj - self.size_gc_header()).signed[1] - size = self.objectmodel.fixed_size(typeid) - if self.objectmodel.is_varsize(typeid): - lenaddr = obj + self.objectmodel.varsize_offset_to_length(typeid) + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + lenaddr = obj + self.varsize_offset_to_length(typeid) length = lenaddr.signed[0] - size += length * self.objectmodel.varsize_item_sizes(typeid) + size += length * self.varsize_item_sizes(typeid) return size - def size_gc_header(self): + def size_gc_header(self, typeid=0): return lltypesimulation.sizeof(lltype.Signed) * 2 def init_gc_object(self, addr, typeid): Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Mon Aug 29 16:59:47 2005 @@ -38,16 +38,15 @@ from pypy.rpython.memory.gc import MarkSweepGC, SemiSpaceGC use_gc = MarkSweepGC def create_mark_sweep_gc(llinterp, flowgraphs): - from pypy.rpython.memory.gcwrapper import GcWrapper, LLInterpObjectModel - #XXX hackish: we need the gc before the object model is ready - gc = use_gc(None, 4096) - fgcc = FlowGraphConstantConverter(flowgraphs, gc) - fgcc.convert() - om = LLInterpObjectModel(llinterp, fgcc.cvter.types, - fgcc.cvter.type_to_typeid, - fgcc.cvter.constantroots) - gc.objectmodel = om - wrapper = GcWrapper(llinterp, gc) + from pypy.rpython.memory.gcwrapper import GcWrapper, QueryTypes + # XXX there might me GCs that have headers that depend on the type + # therefore we have to change the query functions to annotatable ones later + qt = QueryTypes(llinterp) + gc = use_gc(4096, None, *qt.get_setup_query_functions()) + fgcc = FlowGraphConstantConverter(flowgraphs, gc, qt) + fgcc.convert() + gc.set_query_functions(*qt.create_query_functions()) + wrapper = GcWrapper(llinterp, gc, qt, fgcc.cvter.constantroots) return wrapper -prepare_graphs_and_create_gc = create_mark_sweep_gc +prepare_graphs_and_create_gc = create_no_gc Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Mon Aug 29 16:59:47 2005 @@ -5,86 +5,144 @@ from pypy.rpython.memory import lltypesimulation from pypy.rpython.memory.gc import MarkSweepGC -class LLInterpObjectModel(object): - def __init__(self, llinterp, types, - type_to_typeid, constantroots): - self.type_to_typeid = type_to_typeid - self.constantroots = constantroots - self.roots = [] - self.pseudo_root_pointers = NULL +class QueryTypes(object): + def __init__(self, llinterp): self.llinterp = llinterp - self.types = types - self._is_varsize = [] - self._offsets_to_gc_pointers = [] - self._fixed_size = [] - self._varsize_item_sizes = [] - self._varsize_offset_to_variable_part = [] - self._varsize_offset_to_length = [] - self._varsize_offsets_to_gcpointers_in_var_part = [] - tttid = zip(*zip(*type_to_typeid.items())[::-1]) + self.types = [] + self.type_to_typeid = {} + + def get_typeid(self, TYPE): + if TYPE not in self.type_to_typeid: + index = len(self.types) + self.type_to_typeid[TYPE] = index + self.types.append(TYPE) + return index + typeid = self.type_to_typeid[TYPE] + return typeid + + def create_query_functions(self): + _is_varsize = [] + _offsets_to_gc_pointers = [] + _fixed_size = [] + _varsize_item_sizes = [] + _varsize_offset_to_variable_part = [] + _varsize_offset_to_length = [] + _varsize_offsets_to_gcpointers_in_var_part = [] + tttid = zip(*zip(*self.type_to_typeid.items())[::-1]) tttid.sort() tttid = zip(*zip(*tttid)[::-1]) for TYPE, typeid in tttid: varsize = (isinstance(TYPE, lltype.Array) or (isinstance(TYPE, lltype.Struct) and TYPE._arrayfld is not None)) - self._is_varsize.append(varsize) - self._offsets_to_gc_pointers.append( + _is_varsize.append(varsize) + _offsets_to_gc_pointers.append( lltypelayout.offsets_to_gc_pointers(TYPE)) - self._fixed_size.append( - lltypelayout.get_fixed_size(TYPE)) + _fixed_size.append(lltypelayout.get_fixed_size(TYPE)) if varsize: - self._varsize_item_sizes.append( - lltypelayout.get_variable_size(TYPE)) - self._varsize_offset_to_variable_part.append( + _varsize_item_sizes.append(lltypelayout.get_variable_size(TYPE)) + _varsize_offset_to_variable_part.append( lltypelayout.get_fixed_size(TYPE)) - self._varsize_offset_to_length.append( + _varsize_offset_to_length.append( lltypelayout.varsize_offset_to_length(TYPE)) - self._varsize_offsets_to_gcpointers_in_var_part.append( + _varsize_offsets_to_gcpointers_in_var_part.append( lltypelayout.varsize_offsets_to_gcpointers_in_var_part(TYPE)) else: - self._varsize_item_sizes.append(0) - self._varsize_offset_to_variable_part.append(0) - self._varsize_offset_to_length.append(0) - self._varsize_offsets_to_gcpointers_in_var_part.append([]) - - def update_changed_addresses(self): - for i, root in enumerate(self.roots): - if root._address != self.pseudo_root_pointers.address[i]: - print "address changed:", root._address, self.pseudo_root_pointers.address[i] - root.__dict__['_address'] = self.pseudo_root_pointers.address[i] - - def get_typeid(self, TYPE): - typeid = self.type_to_typeid[TYPE] - return typeid + _varsize_item_sizes.append(0) + _varsize_offset_to_variable_part.append(0) + _varsize_offset_to_length.append(0) + _varsize_offsets_to_gcpointers_in_var_part.append([]) + def is_varsize(typeid): + return _is_varsize[typeid] + def offsets_to_gc_pointers(typeid): + return _offsets_to_gc_pointers[typeid] + def fixed_size(typeid): + return _fixed_size[typeid] + def varsize_item_sizes(typeid): + return _varsize_item_sizes[typeid] + def varsize_offset_to_variable_part(typeid): + return _varsize_offset_to_variable_part[typeid] + def varsize_offset_to_length(typeid): + return _varsize_offset_to_length[typeid] + def varsize_offsets_to_gcpointers_in_var_part(typeid): + return _varsize_offsets_to_gcpointers_in_var_part[typeid] + return (is_varsize, offsets_to_gc_pointers, fixed_size, + varsize_item_sizes, varsize_offset_to_variable_part, + varsize_offset_to_length, + varsize_offsets_to_gcpointers_in_var_part) def is_varsize(self, typeid): assert typeid >= 0 - return self._is_varsize[typeid] + TYPE = self.types[typeid] + return (isinstance(TYPE, lltype.Array) or + (isinstance(TYPE, lltype.Struct) and + TYPE._arrayfld is not None)) def offsets_to_gc_pointers(self, typeid): assert typeid >= 0 - return self._offsets_to_gc_pointers[typeid] + return lltypelayout.offsets_to_gc_pointers(self.types[typeid]) def fixed_size(self, typeid): assert typeid >= 0 - return self._fixed_size[typeid] + return lltypelayout.get_fixed_size(self.types[typeid]) def varsize_item_sizes(self, typeid): assert typeid >= 0 - return self._varsize_item_sizes[typeid] + if self.is_varsize(typeid): + return lltypelayout.get_variable_size(self.types[typeid]) + else: + return 0 def varsize_offset_to_variable_part(self, typeid): assert typeid >= 0 - return self._varsize_offset_to_variable_part[typeid] + if self.is_varsize(typeid): + return lltypelayout.get_fixed_size(self.types[typeid]) + else: + return 0 def varsize_offset_to_length(self, typeid): assert typeid >= 0 - return self._varsize_offset_to_length[typeid] + if self.is_varsize(typeid): + return lltypelayout.varsize_offset_to_length(self.types[typeid]) + else: + return 0 def varsize_offsets_to_gcpointers_in_var_part(self, typeid): assert typeid >= 0 - return self._varsize_offsets_to_gcpointers_in_var_part[typeid] + if self.is_varsize(typeid): + return lltypelayout.varsize_offsets_to_gcpointers_in_var_part( + self.types[typeid]) + else: + return 0 + + def get_setup_query_functions(self): + return (self.is_varsize, self.offsets_to_gc_pointers, self.fixed_size, + self.varsize_item_sizes, self.varsize_offset_to_variable_part, + self.varsize_offset_to_length, + self.varsize_offsets_to_gcpointers_in_var_part) + +class GcWrapper(object): + def __init__(self, llinterp, gc, qt, constantroots): + self.llinterp = llinterp + self.gc = gc + self.gc.get_roots = self.get_roots + self.query_types = qt + self.constantroots = constantroots + self.pseudo_root_pointers = NULL + self.roots = [] + + def malloc(self, TYPE, size=0): + typeid = self.query_types.get_typeid(TYPE) + address = self.gc.malloc(typeid, size) + result = lltypesimulation.init_object_on_address(address, TYPE, size) + self.update_changed_addresses() + return result + + def update_changed_addresses(self): + for i, root in enumerate(self.roots): + if root._address != self.pseudo_root_pointers.address[i]: + print "address changed:", root._address, self.pseudo_root_pointers.address[i] + root.__dict__['_address'] = self.pseudo_root_pointers.address[i] def get_roots(self): print "getting roots" @@ -103,18 +161,3 @@ self.pseudo_root_pointers.address[i] = root._address ll.append(self.pseudo_root_pointers + INT_SIZE * i) return ll - - -class GcWrapper(object): - def __init__(self, llinterp, gc): - self.llinterp = llinterp - self.objectmodel = gc.objectmodel - assert isinstance(self.objectmodel, LLInterpObjectModel) - self.gc = gc - - def malloc(self, TYPE, size=0): - typeid = self.objectmodel.get_typeid(TYPE) - address = self.gc.malloc(typeid, size) - result = lltypesimulation.init_object_on_address(address, TYPE, size) - self.objectmodel.update_changed_addresses() - return result Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Mon Aug 29 16:59:47 2005 @@ -47,7 +47,7 @@ return self.layout_mapping[typeid] class TestMarkSweepGC(object): - def test_simple(self): + def DONOTtest_simple(self): variables = raw_malloc(4 * INT_SIZE) roots = [variables + i * INT_SIZE for i in range(4)] layout0 = [] #int @@ -155,7 +155,7 @@ def teardown_class(cls): gclltype.use_gc = cls.old - def test_simple(self): + def DONOTtest_simple(self): variables = raw_malloc(4 * INT_SIZE) roots = [variables + i * INT_SIZE for i in range(4)] layout0 = [] #int From arigo at codespeak.net Mon Aug 29 17:08:56 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 17:08:56 +0200 (CEST) Subject: [pypy-svn] r17041 - pypy/dist/pypy/translator/c Message-ID: <20050829150856.8F00C27B64@code1.codespeak.net> Author: arigo Date: Mon Aug 29 17:08:54 2005 New Revision: 17041 Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/node.py Log: Some hacks and some clean-ups to try(?) to get a bit more speed out of the incredibly slow C code generator. Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Mon Aug 29 17:08:54 2005 @@ -18,7 +18,7 @@ """ if USESLOTS: - __slots__ = """graph db + __slots__ = """graph db gcpolicy cpython_exc more_ll_values vars @@ -27,6 +27,7 @@ def __init__(self, graph, db, cpython_exc=False): self.graph = graph self.db = db + self.gcpolicy = db.gcpolicy self.cpython_exc = cpython_exc # # collect all variables and constants used in the body, @@ -168,26 +169,27 @@ linklocalvars = linklocalvars or {} for v in to_release: linklocalvars[v] = self.expr(v) - is_alive = linklocalvars.copy() + is_alive_and_dies = linklocalvars.copy() assignments = [] - stay_alive = [] + multiple_times_alive = [] for a1, a2 in zip(link.args, link.target.inputargs): - if self.lltypemap(a2) == Void: + a2type, a2typename = self.lltypes[id(a2)] + if a2type == Void: continue if a1 in linklocalvars: src = linklocalvars[a1] else: src = self.expr(a1) - dest = self.expr(a2) - assignments.append((self.lltypename(a2), dest, src)) - if a1 in is_alive: - del is_alive[a1] + dest = LOCALVAR % a2.name + assignments.append((a2typename, dest, src)) + if a1 in is_alive_and_dies: + del is_alive_and_dies[a1] else: - assert self.lltypemap(a1) == self.lltypemap(a2) - stay_alive.append(a2) + #assert self.lltypemap(a1) == self.lltypemap(a2) + multiple_times_alive.append(a2) # warning, the order below is delicate to get right: # 1. forget the old variables that are not passed over - for v in is_alive: + for v in is_alive_and_dies: line = self.pop_alive(v, linklocalvars[v]) if line: yield line @@ -195,7 +197,7 @@ for line in gen_assignments(assignments): yield line # 3. keep alive the new variables if needed - for a2 in stay_alive: + for a2 in multiple_times_alive: line = self.push_alive(a2) if line: yield line @@ -211,28 +213,37 @@ assert graph.startblock is allblocks[0] # generate the body of each block + push_alive_op_result = self.gcpolicy.push_alive_op_result for block in allblocks: + myblocknum = blocknum[block] yield '' - yield 'block%d:' % blocknum[block] + yield 'block%d:' % myblocknum to_release = list(block.inputargs) + reachable_err = -1 # the number of the first reachable err label for op in block.operations: - err = 'err%d_%d' % (blocknum[block], len(to_release)) + err = 'err%d_%d' % (myblocknum, len(to_release)) macro = 'OP_%s' % op.opname.upper() meth = getattr(self, macro, None) if meth: - yield meth(op, err) + line = meth(op, err) else: lst = [self.expr(v) for v in op.args] lst.append(self.expr(op.result)) lst.append(err) - yield '%s(%s);' % (macro, ', '.join(lst)) + line = '%s(%s);' % (macro, ', '.join(lst)) + yield line + if line.find(err) >= 0: + reachable_err = len(to_release) to_release.append(op.result) - line = self.db.gcpolicy.push_alive_op_result(op.opname, LOCALVAR % op.result.name, self.lltypemap(op.result)) - if line: - yield line + T = self.lltypemap(op.result) + if T != Void: + res = LOCALVAR % op.result.name + line = push_alive_op_result(op.opname, res, T) + if line: + yield line - err_reachable = False + fallthrough = False if len(block.exits) == 0: if len(block.inputargs) == 2: # exc_cls, exc_value # exceptional return block @@ -263,7 +274,8 @@ # which goes to the last err%d_%d label written above. yield '' to_release.pop() # skip default error handling for this label - yield 'err%d_%d:' % (blocknum[block], len(to_release)) + yield 'err%d_%d:' % (myblocknum, len(to_release)) + reachable_err = len(to_release) # XXX assert they are == ? yield '' for link in block.exits[1:]: assert issubclass(link.exitcase, Exception) @@ -297,7 +309,7 @@ for op in gen_link(link, d): yield '\t' + op yield '}' - err_reachable = True + fallthrough = True else: # block ending in a switch on a value TYPE = self.lltypemap(block.exitswitch) @@ -329,15 +341,16 @@ yield op yield '' - while to_release: - v = to_release.pop() - if err_reachable: - yield self.pop_alive(v) - yield 'err%d_%d:' % (blocknum[block], len(to_release)) - err_reachable = True - if err_reachable: - for line in self.return_with_error(): - yield line + for i in range(reachable_err, -1, -1): + if not fallthrough: + yield 'err%d_%d:' % (myblocknum, i) + else: + fallthrough = False # this label was already generated + if i == 0: + for line in self.return_with_error(): + yield line + else: + yield self.pop_alive(to_release[i-1]) # ____________________________________________________________ @@ -398,9 +411,8 @@ newvalue = self.expr(op.result, special_case_void=False) result = ['%s = %s;' % (newvalue, sourceexpr)] # need to adjust the refcount of the result only for PyObjects - line = self.pyobj_incref_expr(newvalue, T) - if line: - result.append(line) + if T == PyObjPtr: + result.append(self.pyobj_incref_expr(newvalue, T)) result = '\t'.join(result) if T == Void: result = '/* %s */' % result @@ -411,7 +423,7 @@ result = ['%s = %s;' % (targetexpr, newvalue)] # insert write barrier T = self.lltypemap(op.args[2]) - self.db.gcpolicy.write_barrier(result, newvalue, T, targetexpr) + self.gcpolicy.write_barrier(result, newvalue, T, targetexpr) result = '\t'.join(result) if T == Void: result = '/* %s */' % result @@ -477,9 +489,7 @@ eresult = self.expr(op.result) esize = 'sizeof(%s)' % cdecl(typename, '') - result = list(self.db.gcpolicy.zero_malloc(TYPE, esize, eresult, err)) - - return '\t'.join(result) + return self.gcpolicy.zero_malloc(TYPE, esize, eresult, err) def OP_MALLOC_VARSIZE(self, op, err): TYPE = self.lltypemap(op.result).TO @@ -502,12 +512,9 @@ esize = 'sizeof(%s)+((%s-1)*sizeof(%s))' % (cdecl(typename, ''), elength, cdecl(itemtypename, '')) - result = list(self.db.gcpolicy.zero_malloc(TYPE, esize, eresult, err)) - result.append( - '%s->%s = %s;' % (eresult, lenfld, - elength), - ) - return '\t'.join(result) + result = self.gcpolicy.zero_malloc(TYPE, esize, eresult, err) + result += '\t%s->%s = %s;' % (eresult, lenfld, elength) + return result def OP_CAST_POINTER(self, op, err): TYPE = self.lltypemap(op.result) @@ -517,9 +524,8 @@ cdecl(typename, ''), self.expr(op.args[0]))) - line = self.pyobj_incref(op.result) - if line: - result.append(line) + if TYPE == PyObjPtr: + result.append(self.pyobj_incref(op.result)) return '\t'.join(result) def OP_SAME_AS(self, op, err): @@ -529,9 +535,8 @@ if TYPE != Void: result.append('%s = %s;' % (self.expr(op.result), self.expr(op.args[0]))) - line = self.pyobj_incref(op.result) - if line: - result.append(line) + if TYPE == PyObjPtr: + result.append(self.pyobj_incref(op.result)) return '\t'.join(result) def pyobj_incref(self, v): @@ -539,24 +544,21 @@ return self.pyobj_incref_expr(LOCALVAR % v.name, T) def pyobj_incref_expr(self, expr, T): - return self.db.gcpolicy.pyobj_incref(expr, T) + return self.gcpolicy.pyobj_incref(expr, T) def pyobj_decref_expr(self, expr, T): - return self.db.gcpolicy.pyobj_decref(expr, T) + return self.gcpolicy.pyobj_decref(expr, T) def push_alive(self, v): T = self.lltypemap(v) - return self.push_alive_expr(LOCALVAR % v.name, T) + return self.gcpolicy.push_alive(LOCALVAR % v.name, T) def pop_alive(self, v, expr=None): T = self.lltypemap(v) - return self.pop_alive_expr(expr or (LOCALVAR % v.name), T) - - def push_alive_expr(self, expr, T): - return self.db.gcpolicy.push_alive(expr, T) + return self.gcpolicy.pop_alive(expr or (LOCALVAR % v.name), T) def pop_alive_expr(self, expr, T): - return self.db.gcpolicy.pop_alive(expr, T) + return self.gcpolicy.pop_alive(expr, T) assert not USESLOTS or '__dict__' not in dir(FunctionCodeGenerator) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Mon Aug 29 17:08:54 2005 @@ -12,9 +12,7 @@ self.db = db def pyobj_incref(self, expr, T): - if T == PyObjPtr: - return 'Py_XINCREF(%s);' % expr - return '' + return 'Py_XINCREF(%s);' % expr def pyobj_decref(self, expr, T): return 'Py_XDECREF(%s);' % expr @@ -50,24 +48,24 @@ return None def common_gcheader_definition(self, defnode): - return [] + return '' def common_after_definition(self, defnode): return [] def common_gcheader_initializationexpr(self, defnode): - return [] + return '' struct_gcheader_definition = common_gcheader_definition struct_after_definition = common_after_definition - struct_gcheader_initialitionexpr = common_gcheader_initializationexpr + struct_gcheader_initializationexpr = common_gcheader_initializationexpr def prepare_nested_gcstruct(self, structdefnode, INNER): pass array_gcheader_definition = common_gcheader_definition array_after_definition = common_after_definition - array_gcheader_initialitionexpr = common_gcheader_initializationexpr + array_gcheader_initializationexpr = common_gcheader_initializationexpr def gc_libraries(self): return [] @@ -139,7 +137,7 @@ return 'refcount' def common_gcheader_definition(self, defnode): - yield 'long refcount;' + return 'long refcount;' def common_after_definition(self, defnode): if defnode.gcinfo: @@ -148,11 +146,10 @@ yield 'void %s(struct %s *);' % (gcinfo.deallocator, defnode.name) def common_gcheader_initializationexpr(self, defnode): - yield 'REFCOUNT_IMMORTAL,' + return 'REFCOUNT_IMMORTAL,' def deallocator_lines(self, defnode, prefix): - for line in defnode.visitor_lines(prefix, self.generic_dealloc): - yield line + return defnode.visitor_lines(prefix, self.generic_dealloc) # for structs @@ -216,7 +213,7 @@ yield '}' - struct_gcheader_initialitionexpr = common_gcheader_initializationexpr + struct_gcheader_initializationexpr = common_gcheader_initializationexpr # for arrays @@ -239,7 +236,7 @@ yield '\tOP_FREE(a);' yield '}' - array_gcheader_initialitionexpr = common_gcheader_initializationexpr + array_gcheader_initializationexpr = common_gcheader_initializationexpr # for rtti node @@ -252,7 +249,7 @@ # zero malloc impl def zero_malloc(self, TYPE, esize, eresult, err): - yield 'OP_ZERO_MALLOC(%s, %s, %s);' % (esize, + return 'OP_ZERO_MALLOC(%s, %s, %s);' % (esize, eresult, err) @@ -338,12 +335,12 @@ def zero_malloc(self, TYPE, esize, eresult, err): gcinfo = self.db.gettypedefnode(TYPE).gcinfo if gcinfo and gcinfo.finalizer: - yield 'OP_BOEHM_ZERO_MALLOC_FINALIZER(%s, %s, %s, %s);' % (esize, + return 'OP_BOEHM_ZERO_MALLOC_FINALIZER(%s, %s, %s, %s);' % (esize, eresult, gcinfo.finalizer, err) else: - yield 'OP_BOEHM_ZERO_MALLOC(%s, %s, %s);' % (esize, + return 'OP_BOEHM_ZERO_MALLOC(%s, %s, %s);' % (esize, eresult, err) @@ -361,8 +358,7 @@ class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode): globalcontainer = True includes = () - typename = 'long @' - implementationtypename = typename + typename = 'char @' def __init__(self, db, T, obj): assert T == RuntimeTypeInfo @@ -372,10 +368,10 @@ self.obj = obj defnode = db.gettypedefnode(obj.about) self.name = self.db.namespace.uniquename('g_rtti_v_'+ defnode.barename) - self.ptrname = '&%s' % (self.name,) + self.ptrname = '(&%s)' % (self.name,) def enum_dependencies(self): return [] def implementation(self): - yield 'long %s = %d;' % (self.name, id(self.obj)) + yield 'char %s /* uninitialized */;' % self.name Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Mon Aug 29 17:08:54 2005 @@ -104,7 +104,8 @@ yield 'struct %s {' % self.name # gcheader if needs_gcheader(self.STRUCT): - for line in gcpolicy.struct_gcheader_definition(self): + line = gcpolicy.struct_gcheader_definition(self) + if line: yield '\t' + line for name, typename in self.fields: @@ -189,7 +190,8 @@ yield 'struct %s {' % self.name # gcheader if needs_gcheader(self.ARRAY): - for line in gcpolicy.array_gcheader_definition(self): + line = gcpolicy.array_gcheader_definition(self) + if line: yield '\t' + line yield '\tlong length;' line = '%s;' % cdecl(self.itemtypename, 'items[%d]'% self.varlength) @@ -330,7 +332,8 @@ def initializationexpr(self, decoration=''): yield '{' if needs_gcheader(self.T): - for line in self.db.gcpolicy.struct_gcheader_initialitionexpr(self): + line = self.db.gcpolicy.struct_gcheader_initializationexpr(self) + if line: yield '\t' + line defnode = self.db.gettypedefnode(self.T) for name in self.T._names: @@ -360,7 +363,8 @@ def initializationexpr(self, decoration=''): yield '{' if needs_gcheader(self.T): - for line in self.db.gcpolicy.array_gcheader_initialitionexpr(self): + line = self.db.gcpolicy.array_gcheader_initializationexpr(self) + if line: yield '\t' + line if self.T.OF == Void or len(self.obj.items) == 0: yield '\t%d' % len(self.obj.items) @@ -464,25 +468,24 @@ # # generate the body itself # - lineprefix = '' - for line in funcgen.cfunction_body(): + bodyiter = funcgen.cfunction_body() + for line in bodyiter: # performs some formatting on the generated body: # indent normal lines with tabs; indent labels less than the rest if line.endswith(':'): if line.startswith('err'): - lineprefix += '\t' + line - continue # merge this 'err:' label with the following line + try: + nextline = bodyiter.next() + except StopIteration: + nextline = '' + # merge this 'err:' label with the following line + line = '\t%s\t%s' % (line, nextline) else: - fmt = '%s %s' + line = ' ' + line elif line: - fmt = '%s\t%s' - else: - fmt = '%s%s' - yield fmt % (lineprefix, line) - lineprefix = '' + line = '\t' + line + yield line - if lineprefix: # unlikely - yield lineprefix yield '}' funcgen.implementation_end() From arigo at codespeak.net Mon Aug 29 17:30:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 17:30:12 +0200 (CEST) Subject: [pypy-svn] r17042 - pypy/dist/pypy/tool Message-ID: <20050829153012.743FC27B64@code1.codespeak.net> Author: arigo Date: Mon Aug 29 17:30:11 2005 New Revision: 17042 Modified: pypy/dist/pypy/tool/tls.py Log: Oups. Major performance hit on top of 2.3... Modified: pypy/dist/pypy/tool/tls.py ============================================================================== --- pypy/dist/pypy/tool/tls.py (original) +++ pypy/dist/pypy/tool/tls.py Mon Aug 29 17:30:11 2005 @@ -1,16 +1,25 @@ -"""Thread-local storage.""" +##"""Thread-local storage.""" +## +##try: +## from thread import _local as tlsobject +##except ImportError: # Python < 2.4 +## +## # XXX needs a real object whose attributes are visible only in +## # the thread that reads/writes them. +## +## import autopath, os +## filename = os.path.join(os.path.dirname(autopath.pypydir), +## 'lib-python', '2.4.1', '_threading_local.py') +## glob = {'__name__': '_threading_local'} +## execfile(filename, glob) +## tlsobject = glob['local'] +## del glob, filename -try: - from thread import _local as tlsobject -except ImportError: # Python < 2.4 - # XXX needs a real object whose attributes are visible only in - # the thread that reads/writes them. - import autopath, os - filename = os.path.join(os.path.dirname(autopath.pypydir), - 'lib-python', '2.4.1', '_threading_local.py') - glob = {'__name__': '_threading_local'} - execfile(filename, glob) - tlsobject = glob['local'] - del glob, filename + +class tlsobject(object): + """Storage that is NOT THREAD-LOCAL AT ALL because we don't really need it + at the moment, and it has a performance impact -- a minor one on top of 2.4, + and an extreme one on top of 2.3 :-((((( + """ From cfbolz at codespeak.net Mon Aug 29 18:21:03 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 18:21:03 +0200 (CEST) Subject: [pypy-svn] r17044 - in pypy/dist/pypy/rpython: . memory Message-ID: <20050829162103.093CC27B66@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 18:21:02 2005 New Revision: 17044 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gcwrapper.py Log: commented out prints from the GCs to make annotation possible. change the llinterp and the gcwrapper so that now for every malloc a functionptr is op_direct_called. If the annotation of the gc works it will be possible to attach a graph to this funcptr and then the function will be interpreted by the interpreter Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Aug 29 18:21:02 2005 @@ -275,13 +275,19 @@ def op_malloc(self, obj): if self.llinterpreter.gc is not None: - return self.llinterpreter.gc.malloc(obj) + args = self.llinterpreter.gc.get_arg_malloc(obj) + malloc = self.llinterpreter.gc.get_funcptr_malloc() + result = self.op_direct_call(malloc, *args) + return self.llinterpreter.gc.adjust_result_malloc(result, obj) else: return self.llt.malloc(obj) def op_malloc_varsize(self, obj, size): if self.llinterpreter.gc is not None: - return self.llinterpreter.gc.malloc(obj, size) + args = self.llinterpreter.gc.get_arg_malloc(obj, size) + malloc = self.llinterpreter.gc.get_funcptr_malloc() + result = self.op_direct_call(malloc, *args) + return self.llinterpreter.gc.adjust_result_malloc(result, obj, size) else: return self.llt.malloc(obj, size) Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Mon Aug 29 18:21:02 2005 @@ -5,11 +5,24 @@ from pypy.rpython import lltype from pypy.rpython.objectmodel import free_non_gc_object -import struct +int_size = lltypesimulation.sizeof(lltype.Signed) class GCError(Exception): pass +def get_dummy_annotate(gc): + def dummy_annotate(): + a = gc.malloc(1, 2) + b = gc.malloc(2, 3) + gc.collect() + return a - b + return dummy_annotate + +gc_interface = { + "malloc": lltype.FuncType((lltype.Signed, lltype.Signed), lltype.Signed), + "collect": lltype.FuncType((), lltype.Void), + } + class GCBase(object): _alloc_flavor_ = "raw" @@ -25,7 +38,9 @@ self.varsize_offset_to_variable_part = varsize_offset_to_variable_part self.varsize_offset_to_length = varsize_offset_to_length self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part - + + def _freeze_(self): + return True class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" @@ -56,20 +71,20 @@ size += length * self.varsize_item_sizes(typeid) size_gc_header = self.size_gc_header() result = raw_malloc(size + size_gc_header) - print "mallocing %s, size %s at %s" % (typeid, size, result) +## print "mallocing %s, size %s at %s" % (typeid, size, result) self.init_gc_object(result, typeid) self.malloced_objects.append(result) self.bytes_malloced += size + size_gc_header return result + size_gc_header def collect(self): - print "collecting" +## print "collecting" self.bytes_malloced = 0 roots = self.get_roots() objects = AddressLinkedList() while 1: curr = roots.pop() - print "root: ", curr +## print "root: ", curr if curr == NULL: break # roots is a list of addresses to addresses: @@ -80,7 +95,7 @@ gc_info.signed[0] = 0 while 1: #mark curr = objects.pop() - print "object: ", curr +## print "object: ", curr if curr == NULL: break gc_info = curr - self.size_gc_header() @@ -122,14 +137,14 @@ else: freed_size += size + self.size_gc_header() raw_free(curr) - print "free %s bytes. the heap is %s bytes." % (freed_size, curr_heap_size) +## print "free %s bytes. the heap is %s bytes." % (freed_size, curr_heap_size) free_non_gc_object(self.malloced_objects) self.malloced_objects = newmo if curr_heap_size > self.heap_size: self.heap_size = curr_heap_size def size_gc_header(self, typeid=0): - return lltypesimulation.sizeof(lltype.Signed) * 2 + return int_size * 2 def init_gc_object(self, addr, typeid): addr.signed[0] = 0 @@ -170,13 +185,13 @@ return self.malloc(typeid, length) result = self.free self.init_gc_object(result, typeid) - print "mallocing %s, size %s at %s" % (typeid, size, result) +## print "mallocing %s, size %s at %s" % (typeid, size, result) self.free += totalsize return result + self.size_gc_header() def collect(self): - print "collecting" +## print "collecting" self.fromspace, self.tospace = self.tospace, self.fromspace self.top_of_space = self.tospace + self.space_size roots = self.get_roots() @@ -185,7 +200,7 @@ root = roots.pop() if root == NULL: break - print "root", root, root.address[0] +## print "root", root, root.address[0] root.address[0] = self.copy(root.address[0]) while scan < self.free: curr = scan + self.size_gc_header() @@ -195,9 +210,9 @@ def copy(self, obj): if not self.fromspace <= obj < self.fromspace + self.space_size: return self.copy_non_managed_obj(obj) - print "copying regularly", obj, +## print "copying regularly", obj, if self.is_forwared(obj): - print "already copied to", self.get_forwarding_address(obj) +## print "already copied to", self.get_forwarding_address(obj) return self.get_forwarding_address(obj) else: newaddr = self.free @@ -205,12 +220,12 @@ raw_memcopy(obj - self.size_gc_header(), newaddr, totalsize) self.free += totalsize newobj = newaddr + self.size_gc_header() - print "to", newobj +## print "to", newobj self.set_forwarding_address(obj, newobj) return newobj def copy_non_managed_obj(self, obj): #umph, PBCs, not really copy - print "copying nonmanaged", obj +## print "copying nonmanaged", obj #we have to do the tracing here because PBCs are not moved to tospace self.trace_and_copy(obj) return obj @@ -218,7 +233,7 @@ def trace_and_copy(self, obj): gc_info = obj - self.size_gc_header() typeid = gc_info.signed[1] - print "scanning", obj, typeid +## print "scanning", obj, typeid offsets = self.offsets_to_gc_pointers(typeid) for i in range(len(offsets)): pointer = obj + offsets[i] @@ -259,7 +274,7 @@ def size_gc_header(self, typeid=0): - return lltypesimulation.sizeof(lltype.Signed) * 2 + return int_size * 2 def init_gc_object(self, addr, typeid): addr.signed[0] = 0 Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Mon Aug 29 18:21:02 2005 @@ -1,9 +1,10 @@ +from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython import lltype from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL from pypy.rpython.memory import lltypelayout from pypy.rpython.memory import lltypesimulation -from pypy.rpython.memory.gc import MarkSweepGC +from pypy.rpython.memory import gc class QueryTypes(object): def __init__(self, llinterp): @@ -121,6 +122,7 @@ self.varsize_offset_to_length, self.varsize_offsets_to_gcpointers_in_var_part) + class GcWrapper(object): def __init__(self, llinterp, gc, qt, constantroots): self.llinterp = llinterp @@ -131,9 +133,15 @@ self.pseudo_root_pointers = NULL self.roots = [] - def malloc(self, TYPE, size=0): + def get_arg_malloc(self, TYPE, size=0): typeid = self.query_types.get_typeid(TYPE) - address = self.gc.malloc(typeid, size) + return [typeid, size] + + def get_funcptr_malloc(self): + return self.llinterp.llt.functionptr(gc.gc_interface["malloc"], "malloc", + _callable=self.gc.malloc) + + def adjust_result_malloc(self, address, TYPE, size=0): result = lltypesimulation.init_object_on_address(address, TYPE, size) self.update_changed_addresses() return result From arigo at codespeak.net Mon Aug 29 18:52:06 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 18:52:06 +0200 (CEST) Subject: [pypy-svn] r17045 - pypy/dist/pypy/objspace Message-ID: <20050829165206.2D58227B5E@code1.codespeak.net> Author: arigo Date: Mon Aug 29 18:52:04 2005 New Revision: 17045 Modified: pypy/dist/pypy/objspace/thunk.py Log: Small clean-up of the thunk object space. This should also make it translatable :-) Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Mon Aug 29 18:52:04 2005 @@ -19,60 +19,116 @@ from proxy import create_proxy_space from pypy.interpreter import gateway, baseobjspace, argument +from pypy.interpreter.error import OperationError # __________________________________________________________________________ +# 'w_obj.w_thunkalias' points to another object that 'w_obj' has turned into +baseobjspace.W_Root.w_thunkalias = None + class W_Thunk(baseobjspace.W_Root, object): - def __init__(w_self, space, w_callable, args=argument.Arguments([])): - w_self.space = space + def __init__(w_self, w_callable, args=argument.Arguments([])): w_self.w_callable = w_callable w_self.args = args - w_self.w_value = None -def force(w_self): - while isinstance(w_self, W_Thunk): - if w_self.w_value is None: - w_self.w_value = w_self.space.call_args(w_self.w_callable, - w_self.args) +# special marker to say that w_self has not been computed yet +w_NOT_COMPUTED_THUNK = W_Thunk(None, None) +W_Thunk.w_thunkalias = w_NOT_COMPUTED_THUNK + + +def force(space, w_self): + w_alias = w_self.w_thunkalias + while w_alias is not None: + if w_alias is w_NOT_COMPUTED_THUNK: + w_callable = w_self.w_callable + args = w_self.args + if w_callable is None: + raise OperationError(space.w_RuntimeError, + "thunk is already being computed") w_self.w_callable = None - w_self.args = None - w_self = w_self.w_value + w_self.args = None + w_alias = space.call_args(w_callable, args) + w_self.w_thunkalias = w_alias + w_self = w_alias + w_alias = w_self.w_thunkalias return w_self -def thunk(space, w_callable, __args__): - return W_Thunk(space, w_callable, __args__) -app_thunk = gateway.interp2app(thunk, unwrap_spec=[baseobjspace.ObjSpace, - baseobjspace.W_Root, +def thunk(w_callable, __args__): + return W_Thunk(w_callable, __args__) +app_thunk = gateway.interp2app(thunk, unwrap_spec=[baseobjspace.W_Root, argument.Arguments]) def is_thunk(space, w_obj): - return space.newbool(isinstance(w_obj, W_Thunk)) + return space.newbool(w_obj.w_thunkalias is w_NOT_COMPUTED_THUNK) app_is_thunk = gateway.interp2app(is_thunk) def become(space, w_target, w_source): - while isinstance(w_target, W_Thunk) and w_target.w_value is not None: - w_target = w_target.w_value - w_target.__class__ = W_Thunk - w_target.__dict__ = {'w_value': w_source} + w_target = force(space, w_target) + w_target.w_thunkalias = w_source return space.w_None app_become = gateway.interp2app(become) # __________________________________________________________________________ -operation_args_that_dont_force = { - ('setattr', 2): True, - ('setitem', 2): True, - } +nb_forcing_args = {} + +def setup(): + nb_forcing_args.update({ + 'setattr': 2, # instead of 3 + 'setitem': 2, # instead of 3 + 'get': 2, # instead of 3 + # ---- irregular operations ---- + 'wrap': 0, + 'str_w': 1, + 'int_w': 1, + 'float_w': 1, + 'uint_w': 1, + 'interpclass_w': 1, + 'unwrap': 1, + 'is_true': 1, + 'is_w': 2, + 'newtuple': 0, + 'newlist': 0, + 'newstring': 0, + 'newunicode': 0, + 'newdict': 0, + 'newslice': 0, + 'call_args': 1, + 'marshal_w': 1, + 'log': 1, + }) + for opname, _, arity, _ in baseobjspace.ObjSpace.MethodTable: + nb_forcing_args.setdefault(opname, arity) + for opname in baseobjspace.ObjSpace.IrregularOpTable: + assert opname in nb_forcing_args, "missing %r" % opname + +setup() +del setup + +# __________________________________________________________________________ def proxymaker(space, opname, parentfn): - def proxy(*args): - newargs = [] - for i in range(len(args)): - a = args[i] - if (opname, i) not in operation_args_that_dont_force: - a = force(a) - newargs.append(a) - return parentfn(*newargs) + nb_args = nb_forcing_args[opname] + if nb_args == 0: + return parentfn + if nb_args == 1: + def proxy(w1, *extra): + w1 = force(space, w1) + return parentfn(w1, *extra) + elif nb_args == 2: + def proxy(w1, w2, *extra): + w1 = force(space, w1) + w2 = force(space, w2) + return parentfn(w1, w2, *extra) + elif nb_args == 3: + def proxy(w1, w2, w3, *extra): + w1 = force(space, w1) + w2 = force(space, w2) + w3 = force(space, w3) + return parentfn(w1, w2, w3, *extra) + else: + raise NotImplementedError("operation %r has arity %d" % + (opname, nb_args)) return proxy def Space(space=None): From arigo at codespeak.net Mon Aug 29 19:06:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 19:06:29 +0200 (CEST) Subject: [pypy-svn] r17046 - pypy/dist/pypy/interpreter Message-ID: <20050829170629.91ECC27B60@code1.codespeak.net> Author: arigo Date: Mon Aug 29 19:06:28 2005 New Revision: 17046 Modified: pypy/dist/pypy/interpreter/pycompiler.py Log: Removed a tab. Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Mon Aug 29 19:06:28 2005 @@ -429,7 +429,7 @@ space.wrap(e.offset), space.wrap(e.text)])]) raise OperationError(space.w_SyntaxError, w_synerr) - except UnicodeDecodeError, e: + except UnicodeDecodeError, e: # TODO use a custom UnicodeError raise OperationError(space.w_UnicodeDecodeError, space.newtuple([ space.wrap(e.encoding), space.wrap(e.object), space.wrap(e.start), From arigo at codespeak.net Mon Aug 29 19:06:53 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 19:06:53 +0200 (CEST) Subject: [pypy-svn] r17047 - pypy/dist/pypy/interpreter Message-ID: <20050829170653.D30FA27B60@code1.codespeak.net> Author: arigo Date: Mon Aug 29 19:06:52 2005 New Revision: 17047 Modified: pypy/dist/pypy/interpreter/baseobjspace.py Log: Fix the space operation tables. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Aug 29 19:06:52 2005 @@ -639,7 +639,7 @@ ('get', 'get', 3, ['__get__']), ('set', 'set', 3, ['__set__']), ('delete', 'delete', 2, ['__delete__']), - ('userdel', 'del', 2, ['__del__']), + ('userdel', 'del', 1, ['__del__']), ] ObjSpace.BuiltinModuleTable = [ @@ -724,6 +724,8 @@ 'newunicode', 'newdict', 'newslice', - 'call_args' + 'call_args', + 'marshal_w', + 'log', ] From arigo at codespeak.net Mon Aug 29 19:08:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 19:08:18 +0200 (CEST) Subject: [pypy-svn] r17048 - in pypy/dist/pypy/objspace: . test Message-ID: <20050829170818.CBDC027B60@code1.codespeak.net> Author: arigo Date: Mon Aug 29 19:08:17 2005 New Revision: 17048 Modified: pypy/dist/pypy/objspace/proxy.py pypy/dist/pypy/objspace/test/test_thunkobjspace.py pypy/dist/pypy/objspace/thunk.py Log: Oups! test_thunkobjspace was patching the global stdobjspace in-place to become a thunk object space. So all tests running after this one would actually run in a thunk object space. Clean-up of the proxying logic: thunk.Space() now always creates a fresh StdObjSpace and then patches it. Modified: pypy/dist/pypy/objspace/proxy.py ============================================================================== --- pypy/dist/pypy/objspace/proxy.py (original) +++ pypy/dist/pypy/objspace/proxy.py Mon Aug 29 19:08:17 2005 @@ -1,4 +1,3 @@ -import py from pypy.interpreter.baseobjspace import ObjSpace # __________________________________________________________________________ @@ -6,19 +5,8 @@ def get_operations(): return [r[0] for r in ObjSpace.MethodTable] + ObjSpace.IrregularOpTable -def create_proxy_space(proxyname, proxymaker, operations=None, space=None): - """ Will create a proxy object space if no space supplied. Otherwise - will patch the supplied space.""" - - options = None - if space is not None and not isinstance(space, ObjSpace): - options = space # XXX temporary hack - space = None - - if space is None: - # make up a StdObjSpace by default - from pypy.objspace import std - space = std.Space(options) +def patch_space_in_place(space, proxyname, proxymaker, operations=None): + """Patches the supplied space.""" if operations is None: operations = get_operations() @@ -32,6 +20,4 @@ prevrepr = space.__repr__() space.__repr__ = lambda: '%s(%s)' % (proxyname, prevrepr) - return space - # __________________________________________________________________________ Modified: pypy/dist/pypy/objspace/test/test_thunkobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_thunkobjspace.py (original) +++ pypy/dist/pypy/objspace/test/test_thunkobjspace.py Mon Aug 29 19:08:17 2005 @@ -2,8 +2,8 @@ class AppTest_Thunk: - def setup_class(cls): - cls.space = thunk.Space(cls.space) + def setup_class(cls): + cls.space = thunk.Space() def test_simple(self): computed = [] Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Mon Aug 29 19:08:17 2005 @@ -17,7 +17,7 @@ """ -from proxy import create_proxy_space +from pypy.objspace.proxy import patch_space_in_place from pypy.interpreter import gateway, baseobjspace, argument from pypy.interpreter.error import OperationError @@ -110,8 +110,8 @@ def proxymaker(space, opname, parentfn): nb_args = nb_forcing_args[opname] if nb_args == 0: - return parentfn - if nb_args == 1: + proxy = None + elif nb_args == 1: def proxy(w1, *extra): w1 = force(space, w1) return parentfn(w1, *extra) @@ -131,8 +131,11 @@ (opname, nb_args)) return proxy -def Space(space=None): - space = create_proxy_space('thunk', proxymaker, space=space) +def Space(*args, **kwds): + # for now, always make up a wrapped StdObjSpace + from pypy.objspace import std + space = std.Space(*args, **kwds) + patch_space_in_place(space, 'thunk', proxymaker) space.setitem(space.builtin.w_dict, space.wrap('thunk'), space.wrap(app_thunk)) space.setitem(space.builtin.w_dict, space.wrap('is_thunk'), From cfbolz at codespeak.net Mon Aug 29 19:40:41 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 19:40:41 +0200 (CEST) Subject: [pypy-svn] r17049 - pypy/dist/pypy/rpython Message-ID: <20050829174041.C2CCA27B60@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 19:40:40 2005 New Revision: 17049 Modified: pypy/dist/pypy/rpython/rbuiltin.py Log: free_non_gc_object should really be flavored_free Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Mon Aug 29 19:40:40 2005 @@ -328,6 +328,6 @@ flavor = hop.args_r[0].getflavor() assert not flavor.startswith('gc') cflavor = hop.inputconst(lltype.Void, flavor) - return hop.genop('free_non_gc_object', [cflavor, vinst]) + return hop.genop('flavored_free', [cflavor, vinst]) BUILTIN_TYPER[objectmodel.free_non_gc_object] = rtype_free_non_gc_object From cfbolz at codespeak.net Mon Aug 29 19:43:00 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 19:43:00 +0200 (CEST) Subject: [pypy-svn] r17050 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050829174300.03C7727B60@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 19:42:59 2005 New Revision: 17050 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: ouch. structs that contain addressed didn't work with the lltypesimulation. test + fix. slightly unclean. Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Mon Aug 29 19:42:59 2005 @@ -15,6 +15,8 @@ return simulatorptr(lltype.Ptr(T), address) elif T == lltype.Bool: return bool(address._load(primitive_to_fmt[T])[0]) + elif T == lladdress.Address: + return (self._address + offset).address[0] elif isinstance(T, lltype.Primitive): return address._load(primitive_to_fmt[T])[0] elif isinstance(T, lltype.Ptr): @@ -61,6 +63,8 @@ if isinstance(T, lltype.Primitive): if T == lltype.Void: return None + elif T == lladdress.Address: + return (self._address + offset).address[0] res = (self._address + offset)._load(primitive_to_fmt[T])[0] if T == lltype.Bool: res = bool(res) @@ -84,7 +88,11 @@ if isinstance(T, lltype.Primitive): if T == lltype.Void: return - (self._address + offset)._store(primitive_to_fmt[T], value) + if T == lladdress.Address: + (self._address + offset).address[0] = value + else: + (self._address + offset)._store(primitive_to_fmt[T], + value) return elif isinstance(T, lltype.Ptr): assert value._TYPE == T @@ -178,7 +186,7 @@ return simulatorptr(PTRTYPE, ptr._address) # for now use the simulators raw_malloc -def malloc(T, n=None, immortal=False): +def malloc(T, n=None, immortal=False, flavor='gc'): fixedsize = get_fixed_size(T) varsize = get_variable_size(T) if n is None: Modified: pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Mon Aug 29 19:42:59 2005 @@ -325,3 +325,8 @@ assert s0.a == s0.a assert not s0.a != s0.a +def test_struct_with_address(): + S = lltype.GcStruct("s", ('a', lladdress.Address)) + s = malloc(S) + s.a = lladdress.NULL + assert s.a == lladdress.NULL From cfbolz at codespeak.net Mon Aug 29 19:48:08 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 19:48:08 +0200 (CEST) Subject: [pypy-svn] r17052 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050829174808.D6D1227B66@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 19:48:07 2005 New Revision: 17052 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: implement op_raw_free in llinterp + test Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Aug 29 19:48:07 2005 @@ -449,6 +449,10 @@ assert self.llt.typeOf(size) == self.llt.Signed return lladdress.raw_malloc(size) + def op_raw_free(self, addr): + assert self.llt.typeOf(addr) == lladdress.Address + lladdress.raw_free(addr) + def op_raw_load(self, addr, typ, offset): assert isinstance(addr, lladdress.address) value = getattr(addr, str(typ).lower())[offset] Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Mon Aug 29 19:48:07 2005 @@ -230,7 +230,9 @@ addr = raw_malloc(10000) same_offset = (addr + 2 * offset - offset) - addr addr.char[offset] = char - return (addr + same_offset).char[0] + result = (addr + same_offset).char[0] + raw_free(addr) + return result res = interpret(f, [10, "c"]) assert res == "c" res = interpret(f, [12, "x"]) @@ -245,7 +247,7 @@ assert not res res = interpret(f, [0]) assert res - + class TestAddressSimulation(object): def test_null_is_singleton(self): From cfbolz at codespeak.net Mon Aug 29 19:56:23 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 19:56:23 +0200 (CEST) Subject: [pypy-svn] r17054 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050829175623.426BA27B6E@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 19:56:21 2005 New Revision: 17054 Modified: pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_support.py Log: support + test for flavored_free in the llinterpreter TODO: add free to the 'real' lltype Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Mon Aug 29 19:56:21 2005 @@ -5,7 +5,7 @@ from pypy.rpython.lltype import Signed, Unsigned, Float, Char, Bool, Void from pypy.rpython.lltype import UniChar, Ptr, typeOf, InvalidCast -from pypy.rpython.memory.lltypesimulation import cast_pointer +from pypy.rpython.memory.lltypesimulation import cast_pointer, free from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr from pypy.rpython.memory.lltypesimulation import pyobjectptr, cast_ptr_to_int Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Mon Aug 29 19:56:21 2005 @@ -197,7 +197,13 @@ size = fixedsize + n * varsize address = lladdress.raw_malloc(size) return init_object_on_address(address, T, n) - + +def free(obj, flavor="gc"): + assert not flavor.startswith("gc") + assert isinstance(obj, simulatorptr) + lladdress.raw_free(obj._address) + obj.__dict__["_address"] = lladdress.NULL + def init_object_on_address(address, T, n=None): result = simulatorptr(lltype.Ptr(T), address) result._zero_initialize(n) Modified: pypy/dist/pypy/rpython/memory/test/test_support.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_support.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_support.py Mon Aug 29 19:56:21 2005 @@ -1,6 +1,7 @@ from pypy.rpython.objectmodel import free_non_gc_object from pypy.rpython.memory.support import AddressLinkedList from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL +from pypy.rpython.memory.test.test_llinterpsim import interpret class TestAddressLinkedList(object): def test_simple_access(self): @@ -28,3 +29,35 @@ free_non_gc_object(ll) raw_free(addr) +def test_linked_list_annotate(): + def f(): + addr = raw_malloc(100) + ll = AddressLinkedList() + ll.append(addr) + ll.append(addr + 1) + ll.append(addr + 2) + a = ll.pop() + res = a == addr + a = ll.pop() + res = res and (a - addr == 1) + a = ll.pop() + res = res and (a - addr == 2) + res = res and (ll.pop() == NULL) + res = res and (ll.pop() == NULL) + ll.append(addr) + ll.free() + free_non_gc_object(ll) + ll = AddressLinkedList() + ll.append(addr) + ll.append(addr + 1) + ll.append(addr + 2) + ll.free() + free_non_gc_object(ll) + raw_free(addr) + return res +## a = RPythonAnnotator() +## res = a.build_types(f, []) +## a.translator.specialize() +## a.translator.view() + res = interpret(f, []) + assert res From arigo at codespeak.net Mon Aug 29 20:08:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 20:08:08 +0200 (CEST) Subject: [pypy-svn] r17055 - in pypy/dist/pypy: annotation translator/test Message-ID: <20050829180808.C064527B6E@code1.codespeak.net> Author: arigo Date: Mon Aug 29 20:08:06 2005 New Revision: 17055 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/classdef.py pypy/dist/pypy/translator/test/test_annrpython.py Log: Yet another case of annotator problem (here creating an infinite recursion with immutablevalue()), discovered by trying to annotate the thunk objspace. See the new test. Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Mon Aug 29 20:08:06 2005 @@ -253,7 +253,8 @@ cdef = ClassDef(cls, self) self.userclasses[cls] = cdef self.userclasseslist.append(cdef) - return self.userclasses[cls] + cdef.setup() + return cdef def getlistdef(self, **flags): """Get the ListDef associated with the current position.""" Modified: pypy/dist/pypy/annotation/classdef.py ============================================================================== --- pypy/dist/pypy/annotation/classdef.py (original) +++ pypy/dist/pypy/annotation/classdef.py Mon Aug 29 20:08:06 2005 @@ -158,8 +158,22 @@ if self.basedef: self.basedef.subdefs[cls] = self + # pass some data to the setup() method, which must be called + # after the __init__() + self.sources_from_the_class = mixeddict, sources + + # forced attributes + if cls in FORCE_ATTRIBUTES_INTO_CLASSES: + for name, s_value in FORCE_ATTRIBUTES_INTO_CLASSES[cls].items(): + self.generalize_attr(name, s_value) + self.find_attribute(name).readonly = False + + def setup(self): # collect the (supposed constant) class attributes - for name, value in mixeddict.items(): + cls = self.cls + d, sources = self.sources_from_the_class + del self.sources_from_the_class # setup() shouldn't be called twice + for name, value in d.items(): # ignore some special attributes if name.startswith('_') and not isinstance(value, FunctionType): continue @@ -168,12 +182,6 @@ value.class_ = cls # remember that this is really a method self.add_source_for_attribute(name, sources.get(name, cls), self) - # forced attributes - if cls in FORCE_ATTRIBUTES_INTO_CLASSES: - for name, s_value in FORCE_ATTRIBUTES_INTO_CLASSES[cls].items(): - self.generalize_attr(name, s_value) - self.find_attribute(name).readonly = False - def add_source_for_attribute(self, attr, source, clsdef=None): """Adds information about a constant source for an attribute. """ Modified: pypy/dist/pypy/translator/test/test_annrpython.py ============================================================================== --- pypy/dist/pypy/translator/test/test_annrpython.py (original) +++ pypy/dist/pypy/translator/test/test_annrpython.py Mon Aug 29 20:08:06 2005 @@ -1508,6 +1508,22 @@ s = a.build_types(f, []) assert s == a.bookkeeper.immutablevalue(123) + def test_class_attribute_is_an_instance_of_itself(self): + class Base: + hello = None + class A(Base): + pass + A.hello = globalA = A() + def f(): + return (Base().hello, globalA) + a = self.RPythonAnnotator() + s = a.build_types(f, []) + assert isinstance(s, annmodel.SomeTuple) + assert isinstance(s.items[0], annmodel.SomeInstance) + assert s.items[0].classdef.cls is A + assert s.items[0].can_be_None + assert s.items[1] == a.bookkeeper.immutablevalue(A.hello) + def g(n): return [0,1,2,n] From cfbolz at codespeak.net Mon Aug 29 20:24:44 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 20:24:44 +0200 (CEST) Subject: [pypy-svn] r17060 - pypy/dist/pypy/rpython Message-ID: <20050829182444.7023627B6E@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 20:24:43 2005 New Revision: 17060 Modified: pypy/dist/pypy/rpython/llinterp.py Log: oops, missing from the last checkin Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Aug 29 20:24:43 2005 @@ -295,6 +295,10 @@ assert isinstance(flavor, str) return self.llt.malloc(obj, flavor=flavor) + def op_flavored_free(self, flavor, obj): + assert isinstance(flavor, str) + self.llt.free(obj, flavor=flavor) + def op_getfield(self, obj, field): assert isinstance(obj, self.llt._ptr) result = getattr(obj, field) From arigo at codespeak.net Mon Aug 29 20:25:49 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 20:25:49 +0200 (CEST) Subject: [pypy-svn] r17061 - pypy/dist/pypy/objspace Message-ID: <20050829182549.C90A027B70@code1.codespeak.net> Author: arigo Date: Mon Aug 29 20:25:48 2005 New Revision: 17061 Modified: pypy/dist/pypy/objspace/thunk.py Log: Removed the default argument that was never used (and that was broken -- passing a [] instead of a space). Added a check that prevents the annotator from flowing a None past this point (though that's probably not important). Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Mon Aug 29 20:25:48 2005 @@ -27,7 +27,7 @@ baseobjspace.W_Root.w_thunkalias = None class W_Thunk(baseobjspace.W_Root, object): - def __init__(w_self, w_callable, args=argument.Arguments([])): + def __init__(w_self, w_callable, args): w_self.w_callable = w_callable w_self.args = args @@ -42,7 +42,7 @@ if w_alias is w_NOT_COMPUTED_THUNK: w_callable = w_self.w_callable args = w_self.args - if w_callable is None: + if w_callable is None or args is None: raise OperationError(space.w_RuntimeError, "thunk is already being computed") w_self.w_callable = None From cfbolz at codespeak.net Mon Aug 29 20:26:22 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 20:26:22 +0200 (CEST) Subject: [pypy-svn] r17062 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050829182622.043B327B70@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 20:26:20 2005 New Revision: 17062 Modified: pypy/dist/pypy/rpython/memory/test/test_address.py pypy/dist/pypy/rpython/raddress.py Log: rtyping for inplace ops for addresses Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Mon Aug 29 20:26:20 2005 @@ -238,6 +238,18 @@ res = interpret(f, [12, "x"]) assert res == "x" + def test_pointer_arithmetic_inplace(self): + def f(offset, char): + addr = raw_malloc(10000) + addr += offset + addr.char[-offset] = char + addr -= offset + return addr.char[0] + res = interpret(f, [10, "c"]) + assert res == "c" + res = interpret(f, [12, "x"]) + assert res == "x" + def test_address_comparison(self): def f(offset): return NULL < NULL + offset or NULL == NULL + offset Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Mon Aug 29 20:26:20 2005 @@ -69,6 +69,7 @@ return hop.genop('adr_add', [v_addr, v_offs], resulttype=Address) return NotImplemented + rtype_inplace_add = rtype_add def rtype_sub((r_addr, r_int), hop): if r_int.lowleveltype == lltype.Signed: @@ -76,6 +77,7 @@ return hop.genop('adr_sub', [v_addr, v_offs], resulttype=Address) return NotImplemented + rtype_inplace_sub = rtype_sub class __extend__(pairtype(AddressRepr, AddressRepr)): From ericvrp at codespeak.net Mon Aug 29 20:32:45 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 29 Aug 2005 20:32:45 +0200 (CEST) Subject: [pypy-svn] r17063 - in pypy/dist/pypy/rpython: . test Message-ID: <20050829183245.4AFAE27B70@code1.codespeak.net> Author: ericvrp Date: Mon Aug 29 20:32:44 2005 New Revision: 17063 Modified: pypy/dist/pypy/rpython/lltype.py pypy/dist/pypy/rpython/test/test_lltype.py Log: * Added _is_atomic method (+test) so backends can know if a Struct/Array/ Primitive/Ptr/etc (incl. children) contains pointers. If they do not contain pointers (i.e. are atomic) then the gc can do a less time consuming job on it. Modified: pypy/dist/pypy/rpython/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltype.py (original) +++ pypy/dist/pypy/rpython/lltype.py Mon Aug 29 20:32:44 2005 @@ -79,6 +79,9 @@ def _inline_is_varsize(self, last): return False + def _is_atomic(self): + return False + class ContainerType(LowLevelType): def _gcstatus(self): @@ -87,6 +90,7 @@ def _inline_is_varsize(self, last): raise TypeError, "%r cannot be inlined in structure" % self + class Struct(ContainerType): def __init__(self, name, *fields): self._name = self.__name__ = name @@ -133,6 +137,12 @@ "inside another container") return False + def _is_atomic(self): + for typ in self._flds.values(): + if not typ._is_atomic(): + return False + return True + def __getattr__(self, name): try: return self._flds[name] @@ -140,15 +150,8 @@ raise AttributeError, 'struct %s has no field %r' % (self._name, name) - - - - def _names_without_voids(self, at_root=True): - #if at_root: #XXX debug stuff - # log('_names_without_voids: ' + self._str_without_voids()) + def _names_without_voids(self): names_without_voids = [name for name in self._names if self._flds[name] is not Void] - #if names_without_voids != list(self._names): - # log('_names_without_voids: removed Void(s) _names=%s, return=%s' % (str(list(self._names)), str(names_without_voids))) return names_without_voids def _str_fields_without_voids(self): @@ -160,9 +163,6 @@ return "%s %s { %s }" % (self.__class__.__name__, self._name, self._str_fields_without_voids()) - - - def _str_fields(self): return ', '.join(['%s: %s' % (name, self._flds[name]) for name in self._names]) @@ -219,6 +219,9 @@ " unless as the last field of a structure") return True + def _is_atomic(self): + return self.OF._is_atomic() + def _str_fields(self): if isinstance(self.OF, Struct): of = self.OF @@ -324,7 +327,10 @@ def _defl(self, parent=None, parentindex=None): return self._default - + + def _is_atomic(self): + return True + _example = _defl Modified: pypy/dist/pypy/rpython/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_lltype.py (original) +++ pypy/dist/pypy/rpython/test/test_lltype.py Mon Aug 29 20:32:44 2005 @@ -407,3 +407,17 @@ assert typeOf(p2) == Ptr(S) assert typeOf(p2.stuff) == Ptr(O) assert parentlink(p2.stuff._obj) == (p2._obj, 'stuff') + +def test_is_atomic(): + U = Struct('inlined', ('z', Signed)) + P = Ptr(RuntimeTypeInfo) + Q = GcStruct('q', ('i', Signed), ('u', U), ('p', P)) + O = OpaqueType('O') + F = GcForwardReference() + assert P._is_atomic() is False + assert Q.i._is_atomic() is True + assert Q.u._is_atomic() is True + assert Q.p._is_atomic() is False + assert Q._is_atomic() is False + assert O._is_atomic() is False + assert F._is_atomic() is False From ericvrp at codespeak.net Mon Aug 29 20:40:27 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 29 Aug 2005 20:40:27 +0200 (CEST) Subject: [pypy-svn] r17064 - in pypy/dist/pypy/translator/c: . src Message-ID: <20050829184027.E8EED27B70@code1.codespeak.net> Author: ericvrp Date: Mon Aug 29 20:40:26 2005 New Revision: 17064 Modified: pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/src/mem.h Log: Added usage of _is_atomic for increased speed execution-speed in genc. Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Mon Aug 29 20:40:26 2005 @@ -334,15 +334,18 @@ def zero_malloc(self, TYPE, esize, eresult, err): gcinfo = self.db.gettypedefnode(TYPE).gcinfo + atomic = ['','_ATOMIC'][TYPE._is_atomic()] if gcinfo and gcinfo.finalizer: - return 'OP_BOEHM_ZERO_MALLOC_FINALIZER(%s, %s, %s, %s);' % (esize, - eresult, - gcinfo.finalizer, - err) + yield 'OP_BOEHM_ZERO_MALLOC_FINALIZER(%s, %s, %s, %s, %s);' % (esize, + eresult, + atomic, + gcinfo.finalizer, + err) else: - return 'OP_BOEHM_ZERO_MALLOC(%s, %s, %s);' % (esize, - eresult, - err) + yield 'OP_BOEHM_ZERO_MALLOC(%s, %s, %s, %s);' % (esize, + eresult, + atomic, + err) def gc_libraries(self): return ['gc'] # xxx on windows? Modified: pypy/dist/pypy/translator/c/src/mem.h ============================================================================== --- pypy/dist/pypy/translator/c/src/mem.h (original) +++ pypy/dist/pypy/translator/c/src/mem.h Mon Aug 29 20:40:26 2005 @@ -49,14 +49,14 @@ #ifdef USING_BOEHM_GC -#define OP_BOEHM_ZERO_MALLOC(size, r, err) { \ - r = (void*) GC_MALLOC(size); \ +#define OP_BOEHM_ZERO_MALLOC(size, r, atomic, err) { \ + r = (void*) GC_MALLOC##atomic(size); \ if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory"); \ memset((void*) r, 0, size); \ } -#define OP_BOEHM_ZERO_MALLOC_FINALIZER(size, r, finalizer, err) { \ - r = (void*) GC_MALLOC(size); \ +#define OP_BOEHM_ZERO_MALLOC_FINALIZER(size, r, atomic, finalizer, err) { \ + r = (void*) GC_MALLOC##atomic(size); \ if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory"); \ GC_REGISTER_FINALIZER(r, finalizer, NULL, NULL, NULL); \ memset((void*) r, 0, size); \ From ericvrp at codespeak.net Mon Aug 29 20:41:51 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 29 Aug 2005 20:41:51 +0200 (CEST) Subject: [pypy-svn] r17065 - pypy/dist/pypy/translator/llvm Message-ID: <20050829184151.A1EBA27B5B@code1.codespeak.net> Author: ericvrp Date: Mon Aug 29 20:41:49 2005 New Revision: 17065 Modified: pypy/dist/pypy/translator/llvm/arraynode.py pypy/dist/pypy/translator/llvm/build_llvm_module.py pypy/dist/pypy/translator/llvm/database.py pypy/dist/pypy/translator/llvm/opwriter.py pypy/dist/pypy/translator/llvm/structnode.py pypy/dist/pypy/translator/llvm/varsize.py Log: Refactoring/simplification so lltype..._is_atomic is shared by pypy-c and pypy-llvm. Modified: pypy/dist/pypy/translator/llvm/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm/arraynode.py Mon Aug 29 20:41:49 2005 @@ -38,14 +38,6 @@ def setup(self): self.db.prepare_type(self.arraytype) - def is_atomic(self): - if isinstance(self.arraytype, lltype.Primitive): - return True - elif isinstance(self.arraytype, lltype.Ptr): - return False - else: - return self.db.is_atomic(self.arraytype) - # ______________________________________________________________________ # entry points from genllvm # @@ -62,8 +54,7 @@ log.writeimpl(self.ref) varsize.write_constructor(self.db, codewriter, self.ref, self.constructor_decl, - self.array, - atomicmalloc=self.is_atomic()) + self.array) class VoidArrayTypeNode(LLVMNode): @@ -71,15 +62,13 @@ def __init__(self, db, array): assert isinstance(array, lltype.Array) self.db = db + self.array = array self.ref = "%arraytype.Void" def writedatatypedecl(self, codewriter): td = "%s = type { %s }" % (self.ref, self.db.get_machine_word()) codewriter.append(td) - def is_atomic(self): - return True - class ArrayNode(ConstantLLVMNode): """ An arraynode. Elements can be a primitive, Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm/build_llvm_module.py Mon Aug 29 20:41:49 2005 @@ -31,6 +31,7 @@ "-simplifycfg", ])) +# XXX: TODO: refactoring: use gccas to populate this list # suggested by: gccas /dev/null -o /dev/null -debug-pass=Arguments OPTIMIZATION_SWITCHES = (" ".join([ "-verify -lowersetjmp -funcresolve -raiseallocs -simplifycfg -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -prune-eh -inline -simplify-libcalls -argpromotion -raise -tailduplicate -simplifycfg -scalarrepl -instcombine -break-crit-edges -condprop -tailcallelim -simplifycfg -reassociate -loopsimplify -licm -instcombine -indvars -loop-unroll -instcombine -load-vn -gcse -sccp -instcombine -break-crit-edges -condprop -dse -mergereturn -adce -simplifycfg -deadtypeelim -constmerge -verify" @@ -96,7 +97,8 @@ #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)) if exe_name: - cmds.append("gcc %s.c -c -O2 -fomit-frame-pointer" % (b,)) + #XXX TODO: use CFLAGS when available + cmds.append("gcc %s.c -c -march=pentium4 -O2 -fomit-frame-pointer" % (b,)) cmds.append("gcc %s.o %s -lm -ldl -o %s" % (b, gc_libs, exe_name)) source_files.append("%s.c" % b) Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Mon Aug 29 20:41:49 2005 @@ -363,9 +363,6 @@ return True return False - def is_atomic(self, value): - return self.obj2node[value].is_atomic() - def get_childref(self, parent, child): node = self.obj2node[parent] return node.get_childref(child) Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Mon Aug 29 20:41:49 2005 @@ -406,8 +406,7 @@ targetvar = self.db.repr_arg(op.result) type_ = self.db.repr_type(arg_type) - atomic = self.db.is_atomic(arg_type) - self.codewriter.malloc(targetvar, type_, atomic=atomic) + self.codewriter.malloc(targetvar, type_, atomic=arg_type._is_atomic()) def malloc_varsize(self, op): arg_type = op.args[0].value Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Mon Aug 29 20:41:49 2005 @@ -28,15 +28,6 @@ for field in self._fields(): self.db.prepare_type(field) - def is_atomic(self): - for f in self._fields(): - if isinstance(f, lltype.Ptr): - return False - - if not isinstance(f, lltype.Primitive): - return self.db.is_atomic(f) - - return True # ______________________________________________________________________ # main entry points from genllvm @@ -83,8 +74,7 @@ self.ref, self.constructor_decl, current, - indices_to_array, - atomicmalloc=self.is_atomic()) + indices_to_array) class StructNode(ConstantLLVMNode): """ A struct constant. Can simply contain Modified: pypy/dist/pypy/translator/llvm/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm/varsize.py (original) +++ pypy/dist/pypy/translator/llvm/varsize.py Mon Aug 29 20:41:49 2005 @@ -1,8 +1,8 @@ from pypy.rpython.rstr import STR def write_constructor(db, codewriter, ref, constructor_decl, ARRAY, - indices_to_array=(), atomicmalloc=False): - + indices_to_array=()): + #varsized arrays and structs look like this: #Array: {int length , elemtype*} #Struct: {...., Array} @@ -23,7 +23,7 @@ elemindices = list(indices_to_array) + [("uint", 1), (lentype, "%actuallen")] codewriter.getelementptr("%size", ref + "*", "null", *elemindices) codewriter.cast("%usize", elemtype + "*", "%size", uword) - codewriter.malloc("%ptr", "sbyte", "%usize", atomic=atomicmalloc) + codewriter.malloc("%ptr", "sbyte", "%usize", atomic=ARRAY._is_atomic()) codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") #if ARRAY is STR.chars: From tismer at codespeak.net Mon Aug 29 20:58:15 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 29 Aug 2005 20:58:15 +0200 (CEST) Subject: [pypy-svn] r17066 - pypy/dist/pypy/rpython Message-ID: <20050829185815.BC4FC27B5E@code1.codespeak.net> Author: tismer Date: Mon Aug 29 20:58:14 2005 New Revision: 17066 Modified: pypy/dist/pypy/rpython/rlist.py Log: started low-level list overallocation. This first step just maintains an extra length field. Things still compile well. The next step is to use overallocation for append, and also avoid re-allocating on deletions. After that, it might be considered to drop overallocation from listobject.py, because it is internally supported. Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Mon Aug 29 20:58:14 2005 @@ -63,7 +63,9 @@ if isinstance(self.LIST, GcForwardReference): ITEM = self.item_repr.lowleveltype ITEMARRAY = GcArray(ITEM) - self.LIST.become(GcStruct("list", ("items", Ptr(ITEMARRAY)))) + # XXX we might think of turning length stuff into Unsigned + self.LIST.become(GcStruct("list", ("length", Signed), + ("items", Ptr(ITEMARRAY)))) def convert_const(self, listobj): # get object from bound list method @@ -79,9 +81,10 @@ self.setup() result = malloc(self.LIST, immortal=True) self.list_cache[key] = result - result.items = malloc(self.LIST.items.TO, len(listobj)) + result.length = len(listobj) + result.items = malloc(self.LIST.items.TO, result.length) r_item = self.item_repr - for i in range(len(listobj)): + for i in range(result.length): x = listobj[i] result.items[i] = r_item.convert_const(x) return result @@ -90,8 +93,8 @@ return inputconst(Void, self.item_repr.get_ll_eq_function()) def rtype_bltn_list(self,hop): - v_lst = hop.inputarg(self,0) - return hop.gendirectcall(ll_copy,v_lst) + v_lst = hop.inputarg(self, 0) + return hop.gendirectcall(ll_copy, v_lst) def rtype_len(self, hop): v_lst, = hop.inputargs(self) @@ -159,7 +162,7 @@ def ll_str(l, listrepr): items = l.items - length = len(items) + length = l.length item_repr = listrepr.item_repr temp = malloc(TEMP, length) @@ -304,7 +307,7 @@ def ll_copy(l): items = l.items - length = len(items) + length = l.length new_lst = ll_newlist(typeOf(l), length) i = 0 new_items = new_lst.items @@ -314,35 +317,37 @@ return new_lst def ll_len(l): - return len(l.items) + return l.length def ll_list_is_true(l): # check if a list is True, allowing for None - return bool(l) and len(l.items) != 0 + return bool(l) and l.length != 0 def ll_append(l, newitem): - length = len(l.items) + length = l.length newitems = malloc(typeOf(l).TO.items.TO, length+1) i = 0 while i < length: newitems[i] = l.items[i] i += 1 newitems[length] = newitem + l.length = length + 1 l.items = newitems # this one is for the special case of insert(0, x) def ll_prepend(l, newitem): - length = len(l.items) + length = l.length newitems = malloc(typeOf(l).TO.items.TO, length+1) i = 0 while i < length: newitems[i+1] = l.items[i] i += 1 newitems[0] = newitem + l.length = length + 1 l.items = newitems def ll_insert_nonneg(l, index, newitem): - length = len(l.items) + length = l.length newitems = malloc(typeOf(l).TO.items.TO, length+1) i = 0 while i < index: @@ -353,11 +358,12 @@ while i <= length: newitems[i] = l.items[i-1] i += 1 + l.length = length + 1 l.items = newitems def ll_insert(l, index, newitem): if index < 0: - index += len(l.items) + index += l.length ll_insert_nonneg(l, index, newitem) def ll_pop_nonneg(l, index): @@ -366,7 +372,7 @@ return res def ll_pop_default(l): - index = len(l.items) - 1 + index = l.length - 1 res = l.items[index] newlength = index newitems = malloc(typeOf(l).TO.items.TO, newlength) @@ -374,11 +380,12 @@ while j < newlength: newitems[j] = l.items[j] j += 1 + l.length = newlength l.items = newitems return res def ll_pop_zero(l): - index = len(l.items) - 1 + index = l.length - 1 res = l.items[0] newlength = index newitems = malloc(typeOf(l).TO.items.TO, newlength) @@ -386,18 +393,19 @@ while j < newlength: newitems[j] = l.items[j+1] j += 1 + l.length = newlength l.items = newitems return res def ll_pop(l, index): if index < 0: - index += len(l.items) + index += l.length res = l.items[index] ll_delitem_nonneg(l, index) return res def ll_reverse(l): - length = len(l.items) + length = l.length len2 = length // 2 # moved this out of the loop i = 0 while i < len2: @@ -411,19 +419,19 @@ def ll_getitem(l, i): if i < 0: - i += len(l.items) + i += l.length return l.items[i] def ll_getitem_nonneg_checked(l, i): - if i >= len(l.items): + if i >= l.length: raise IndexError else: return l.items[i] def ll_getitem_checked(l, i): if i < 0: - i += len(l.items) - if i >= len(l.items) or i < 0: + i += l.length + if i >= l.length or i < 0: raise IndexError else: return l.items[i] @@ -432,30 +440,30 @@ l.items[i] = newitem def ll_setitem_nonneg_checked(l, i, newitem): - if i >= len(l.items): + if i >= l.length: raise IndexError l.items[i] = newitem def ll_setitem(l, i, newitem): if i < 0: - i += len(l.items) + i += l.length l.items[i] = newitem def ll_setitem_checked(l, i, newitem): if i < 0: - i += len(l.items) - if i >= len(l.items) or i < 0: + i += l.length + if i >= l.length or i < 0: raise IndexError else: l.items[i] = newitem def ll_delitem_nonneg_checked(l, i): - if i >= len(l.items): + if i >= l.length: raise IndexError ll_delitem_nonneg(l, i) def ll_delitem_nonneg(l, i): - newlength = len(l.items) - 1 + newlength = l.length - 1 newitems = malloc(typeOf(l).TO.items.TO, newlength) j = 0 while j < i: @@ -464,24 +472,26 @@ while j < newlength: newitems[j] = l.items[j+1] j += 1 + l.length = newlength l.items = newitems def ll_delitem(l, i): if i < 0: - i += len(l.items) + i += l.length ll_delitem_nonneg(l, i) def ll_delitem_checked(l, i): if i < 0: - i += len(l.items) - if i >= len(l.items) or i < 0: + i += l.length + if i >= l.length or i < 0: raise IndexError ll_delitem_nonneg(l, i) def ll_concat(l1, l2): - len1 = len(l1.items) - len2 = len(l2.items) - newitems = malloc(typeOf(l1).TO.items.TO, len1 + len2) + len1 = l1.length + len2 = l2.length + newlength = len1 + len2 + newitems = malloc(typeOf(l1).TO.items.TO, newlength) j = 0 while j < len1: newitems[j] = l1.items[j] @@ -492,13 +502,15 @@ i += 1 j += 1 l = malloc(typeOf(l1).TO) + l.length = newlength l.items = newitems return l def ll_extend(l1, l2): - len1 = len(l1.items) - len2 = len(l2.items) - newitems = malloc(typeOf(l1).TO.items.TO, len1 + len2) + len1 = l1.length + len2 = l2.length + newlength = len1 + len2 + newitems = malloc(typeOf(l1).TO.items.TO, newlength) j = 0 while j < len1: newitems[j] = l1.items[j] @@ -508,44 +520,50 @@ newitems[j] = l2.items[i] i += 1 j += 1 + l1.length = newlength l1.items = newitems def ll_listslice_startonly(l1, start): - len1 = len(l1.items) - newitems = malloc(typeOf(l1).TO.items.TO, len1 - start) + len1 = l1.length + newlength = len1 - start + newitems = malloc(typeOf(l1).TO.items.TO, newlength) j = 0 while start < len1: newitems[j] = l1.items[start] start += 1 j += 1 l = malloc(typeOf(l1).TO) + l.length = newlength l.items = newitems return l def ll_listslice(l1, slice): start = slice.start stop = slice.stop - if stop > len(l1.items): - stop = len(l1.items) - newitems = malloc(typeOf(l1).TO.items.TO, stop - start) + if stop > l1.length: + stop = l1.length + newlength = stop - start + newitems = malloc(typeOf(l1).TO.items.TO, newlength) j = 0 while start < stop: newitems[j] = l1.items[start] start += 1 j += 1 l = malloc(typeOf(l1).TO) + l.length = newlength l.items = newitems return l def ll_listslice_minusone(l1): - newlen = len(l1.items) - 1 - assert newlen >= 0 - newitems = malloc(typeOf(l1).TO.items.TO, newlen) + newlength = l1.length - 1 + assert newlength >= 0 + newitems = malloc(typeOf(l1).TO.items.TO, newlength) j = 0 - while j < newlen: + while j < newlength: newitems[j] = l1.items[j] j += 1 l = malloc(typeOf(l1).TO) + l.length = newlength l.items = newitems return l @@ -555,14 +573,15 @@ while j < start: newitems[j] = l1.items[j] j += 1 + l1.length = start l1.items = newitems def ll_listdelslice(l1, slice): start = slice.start stop = slice.stop - if stop > len(l1.items): - stop = len(l1.items) - newlength = len(l1.items) - (stop-start) + if stop > l1.length: + stop = l1.length + newlength = l1.length - (stop-start) newitems = malloc(typeOf(l1).TO.items.TO, newlength) j = 0 while j < start: @@ -572,10 +591,11 @@ newitems[j] = l1.items[stop] stop += 1 j += 1 + l1.length = newlength l1.items = newitems def ll_listsetslice(l1, slice, l2): - count = len(l2.items) + count = l2.length assert count == slice.stop - slice.start, ( "setslice cannot resize lists in RPython") start = slice.start @@ -593,8 +613,8 @@ return True if not l1 or not l2: return False - len1 = len(l1.items) - len2 = len(l2.items) + len1 = l1.length + len2 = l2.length if len1 != len2: return False j = 0 @@ -612,7 +632,7 @@ def ll_listcontains(lst, obj, eqfn): items = lst.items - lng = len(items) + lng = lst.length j = 0 while j < lng: if eqfn is None: @@ -626,7 +646,7 @@ def ll_listindex(lst, obj, eqfn): items = lst.items - lng = len(items) + lng = lst.length j = 0 while j < lng: if eqfn is None: @@ -642,7 +662,7 @@ def ll_mul(l, f): items = l.items - length = len(items) + length = l.length if length == 0 or f <= 0: return ll_newlist(typeOf(l), 0) @@ -665,6 +685,7 @@ def ll_newlist(LISTPTR, length): l = malloc(LISTPTR.TO) + l.length = length l.items = malloc(LISTPTR.TO.items.TO, length) return l @@ -694,6 +715,7 @@ if count < 0: count = 0 l = malloc(LISTPTR.TO) + l.length = count l.items = malloc(LISTPTR.TO.items.TO, count) i = 0 while i < count: @@ -739,12 +761,13 @@ def ll_listnext(iter): l = iter.list index = iter.index - if index >= len(l.items): + if index >= l.length: raise StopIteration iter.index = index + 1 return l.items[index] # ___________________________________________________________ -LIST_OF_STR = GcStruct("list", +LIST_OF_STR = GcStruct("list", + ("length", Signed), ("items", Ptr(GcArray(Ptr(rstr.STR))))) From arigo at codespeak.net Mon Aug 29 21:00:33 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 21:00:33 +0200 (CEST) Subject: [pypy-svn] r17067 - pypy/dist/pypy/bin Message-ID: <20050829190033.3086527B66@code1.codespeak.net> Author: arigo Date: Mon Aug 29 21:00:31 2005 New Revision: 17067 Modified: pypy/dist/pypy/bin/py.py Log: Oups, forgot to check this in. Modified: pypy/dist/pypy/bin/py.py ============================================================================== --- pypy/dist/pypy/bin/py.py (original) +++ pypy/dist/pypy/bin/py.py Mon Aug 29 21:00:31 2005 @@ -53,22 +53,21 @@ return options -def make_objspace(cmdlineopt): - from pypy.objspace import std - if cmdlineopt.objspace not in ('std', 'thunk'): +def make_objspace(cmdlineopt): + if cmdlineopt.objspace == 'std': + from pypy.objspace.std import Space + elif cmdlineopt.objspace == 'thunk': + from pypy.objspace.thunk import Space + else: raise ValueError("cannot instantiate %r space" %(cmdlineopt.objspace,)) - # so far we always need a StdObjSpace - space = std.Space(usemodules = cmdlineopt.usemodules, + space = Space(usemodules = cmdlineopt.usemodules, nofaking = cmdlineopt.nofaking, uselibfile = cmdlineopt.uselibfile, oldstyle = cmdlineopt.oldstyle, parser = cmdlineopt.parser, compiler = cmdlineopt.compiler, ) - if cmdlineopt.objspace == 'thunk': - from pypy.objspace import thunk - space = thunk.Space(space) return space def main_(argv=None): From arigo at codespeak.net Mon Aug 29 21:02:33 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 21:02:33 +0200 (CEST) Subject: [pypy-svn] r17068 - in pypy/dist/pypy: . objspace objspace/test Message-ID: <20050829190233.EE4B027B66@code1.codespeak.net> Author: arigo Date: Mon Aug 29 21:02:32 2005 New Revision: 17068 Modified: pypy/dist/pypy/conftest.py pypy/dist/pypy/objspace/test/test_thunkobjspace.py pypy/dist/pypy/objspace/thunk.py Log: - conftest fix for testing the thunk objspace (the previous version didn't put the 'raises' in the space) - some fix in the thunk, more things marked "XXX in-progress" (It's getting late) Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Mon Aug 29 21:02:32 2005 @@ -46,7 +46,8 @@ return _spacecache[name] except KeyError: assert name in ('std', 'thunk'), name - from pypy.objspace.std import Space + mod = __import__('pypy.objspace.%s' % name, None, None, ['Space']) + Space = mod.Space try: space = Space(uselibfile=option.uselibfile, nofaking=option.nofaking, Modified: pypy/dist/pypy/objspace/test/test_thunkobjspace.py ============================================================================== --- pypy/dist/pypy/objspace/test/test_thunkobjspace.py (original) +++ pypy/dist/pypy/objspace/test/test_thunkobjspace.py Mon Aug 29 21:02:32 2005 @@ -1,9 +1,9 @@ -from pypy.objspace import thunk +from pypy.conftest import gettestobjspace class AppTest_Thunk: def setup_class(cls): - cls.space = thunk.Space() + cls.space = gettestobjspace('thunk') def test_simple(self): computed = [] @@ -58,3 +58,15 @@ become(x, y) become(y, z) assert x is y is z + + def test_thunk_forcing_while_forcing(self): + def f(): + return x+1 + x = thunk(f) + raises(RuntimeError, 'x+1') + + def INPROGRESS_test_thunk_forcing_while_forcing_2(self): + def f(): + return x + x = thunk(f) + raises(RuntimeError, 'x+1') Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Mon Aug 29 21:02:32 2005 @@ -44,10 +44,11 @@ args = w_self.args if w_callable is None or args is None: raise OperationError(space.w_RuntimeError, - "thunk is already being computed") + space.wrap("thunk is already being computed")) w_self.w_callable = None w_self.args = None w_alias = space.call_args(w_callable, args) + # XXX detect circular w_alias result w_self.w_thunkalias = w_alias w_self = w_alias w_alias = w_self.w_thunkalias From cfbolz at codespeak.net Mon Aug 29 21:07:29 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 21:07:29 +0200 (CEST) Subject: [pypy-svn] r17071 - pypy/dist/pypy/rpython/memory Message-ID: <20050829190729.575D027B66@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 21:07:28 2005 New Revision: 17071 Modified: pypy/dist/pypy/rpython/memory/support.py Log: should raw-allocate these Modified: pypy/dist/pypy/rpython/memory/support.py ============================================================================== --- pypy/dist/pypy/rpython/memory/support.py (original) +++ pypy/dist/pypy/rpython/memory/support.py Mon Aug 29 21:07:28 2005 @@ -6,7 +6,7 @@ INT_SIZE = sizeof(lltype.Signed) class AddressLinkedList(object): - _alloc_flavor_ = "" + _alloc_flavor_ = "raw" def __init__(self): self.first = NULL self.last = NULL From cfbolz at codespeak.net Mon Aug 29 21:09:07 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 21:09:07 +0200 (CEST) Subject: [pypy-svn] r17072 - pypy/dist/pypy/rpython/memory Message-ID: <20050829190907.81DF527B66@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 21:09:06 2005 New Revision: 17072 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gcwrapper.py Log: started working on annotation + specializing GCs. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Mon Aug 29 21:09:06 2005 @@ -1,5 +1,5 @@ from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy -from pypy.rpython.memory.lladdress import NULL +from pypy.rpython.memory.lladdress import NULL, address from pypy.rpython.memory.support import AddressLinkedList from pypy.rpython.memory import lltypesimulation from pypy.rpython import lltype @@ -23,6 +23,9 @@ "collect": lltype.FuncType((), lltype.Void), } +def dummy_get_roots(): + return [NULL, raw_malloc(10)] #just random addresses + class GCBase(object): _alloc_flavor_ = "raw" @@ -39,9 +42,6 @@ self.varsize_offset_to_length = varsize_offset_to_length self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part - def _freeze_(self): - return True - class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Mon Aug 29 21:09:06 2005 @@ -169,3 +169,19 @@ self.pseudo_root_pointers.address[i] = root._address ll.append(self.pseudo_root_pointers + INT_SIZE * i) return ll + +class AnnotatingGcWrapper(GcWrapper): + def __init__(self, llinterp, gc, qt, constantroots): + super(AnnotatingGcWrapper, self).__init__(llinterp, gc, qt, + constantroots) + self.annotate_rtype_gc() + + def annotate_rtype_gc(self): + #XXXXX unfinished + func = gc.get_dummy_annotate(self.gc) + self.gc.get_roots = gc.dummy_get_roots + a = RPythonAnnotator() + res = a.build_types(func, []) + a.translator.view() + a.translator.specialize() + self.gc.get_roots = self.get_roots From cfbolz at codespeak.net Mon Aug 29 21:12:15 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 21:12:15 +0200 (CEST) Subject: [pypy-svn] r17073 - pypy/dist/pypy/annotation Message-ID: <20050829191215.9CDA627B66@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 21:12:13 2005 New Revision: 17073 Modified: pypy/dist/pypy/annotation/binaryop.py Log: unions between addresses and someimpossiblevalues and someobjects Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Mon Aug 29 21:12:13 2005 @@ -684,3 +684,19 @@ def sub((s_addr, s_int)): return SomeAddress(is_null=False) +class __extend__(pairtype(SomeAddress, SomeImpossibleValue)): + def union((s_addr, s_imp)): + return s_addr + +class __extend__(pairtype(SomeImpossibleValue, SomeAddress)): + def union((s_imp, s_addr)): + return s_addr + +class __extend__(pairtype(SomeAddress, SomeObject)): + def union((s_addr, s_obj)): + raise UnionError, "union of address and anything else makes no sense" + +class __extend__(pairtype(SomeObject, SomeAddress)): + def union((s_obj, s_addr)): + raise UnionError, "union of address and anything else makes no sense" + From arigo at codespeak.net Mon Aug 29 21:13:40 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 29 Aug 2005 21:13:40 +0200 (CEST) Subject: [pypy-svn] r17074 - pypy/dist/pypy/objspace Message-ID: <20050829191340.0CCC927B66@code1.codespeak.net> Author: arigo Date: Mon Aug 29 21:13:39 2005 New Revision: 17074 Modified: pypy/dist/pypy/objspace/thunk.py Log: Hint for the annotator. Modified: pypy/dist/pypy/objspace/thunk.py ============================================================================== --- pypy/dist/pypy/objspace/thunk.py (original) +++ pypy/dist/pypy/objspace/thunk.py Mon Aug 29 21:13:39 2005 @@ -40,6 +40,7 @@ w_alias = w_self.w_thunkalias while w_alias is not None: if w_alias is w_NOT_COMPUTED_THUNK: + assert isinstance(w_self, W_Thunk) w_callable = w_self.w_callable args = w_self.args if w_callable is None or args is None: From ericvrp at codespeak.net Mon Aug 29 23:12:40 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 29 Aug 2005 23:12:40 +0200 (CEST) Subject: [pypy-svn] r17079 - pypy/dist/pypy/translator/llvm Message-ID: <20050829211240.949D727B56@code1.codespeak.net> Author: ericvrp Date: Mon Aug 29 23:12:38 2005 New Revision: 17079 Modified: pypy/dist/pypy/translator/llvm/arraynode.py pypy/dist/pypy/translator/llvm/database.py pypy/dist/pypy/translator/llvm/funcnode.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/node.py pypy/dist/pypy/translator/llvm/structnode.py Log: Slotified nodes. Memory usage went down from max ~350Mb to ~300Mb. It now takes 35 minutes on my machine to generate the .ll file. Running the llvm toolchain and gcc on that takes another 15 minutes or so. Modified: pypy/dist/pypy/translator/llvm/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm/arraynode.py Mon Aug 29 23:12:38 2005 @@ -6,11 +6,13 @@ log = log.structnode class ArrayTypeNode(LLVMNode): + __slots__ = "db array arraytype ref constructor_ref constructor_decl".split() + def __init__(self, db, array): assert isinstance(array, lltype.Array) self.db = db self.array = array - arraytype = self.arraytype = array.OF + self.arraytype = arraytype = array.OF # ref is used to reference the arraytype in llvm source # constructor_ref is used to reference the constructor # for the array type in llvm source code @@ -58,6 +60,7 @@ class VoidArrayTypeNode(LLVMNode): + __slots__ = "db array ref".split() def __init__(self, db, array): assert isinstance(array, lltype.Array) @@ -75,6 +78,8 @@ a struct, pointer to struct/array """ + __slots__ = "db value arraytype ref".split() + def __init__(self, db, value): assert isinstance(lltype.typeOf(value), lltype.Array) self.db = db @@ -151,6 +156,8 @@ return s class StrArrayNode(ArrayNode): + __slots__ = "".split() + printables = dict([(ord(i), None) for i in ("0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + @@ -173,15 +180,15 @@ return item_length, r class VoidArrayNode(ConstantLLVMNode): + __slots__ = "db value ref".split() def __init__(self, db, value): assert isinstance(lltype.typeOf(value), lltype.Array) self.db = db - self.ref = self.make_ref('%arrayinstance', '') self.value = value + self.ref = self.make_ref('%arrayinstance', '') def constantvalue(self): return "{ %s } {%s %s}" % (self.db.get_machine_word(), self.db.get_machine_word(), len(self.value.items)) - Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Mon Aug 29 23:12:38 2005 @@ -68,7 +68,7 @@ def dump_pbcs(self): r = "" - for k, v in self.obj2node.items(): + for k, v in self.obj2node.iteritems(): if isinstance(k, lltype.LowLevelType): continue @@ -226,7 +226,7 @@ return self.entrynode def getnodes(self): - return self.obj2node.values() + return self.obj2node.itervalues() # __________________________________________________________ # Representing variables and constants in LLVM source code Modified: pypy/dist/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm/funcnode.py Mon Aug 29 23:12:38 2005 @@ -10,6 +10,8 @@ log = log.funcnode class FuncTypeNode(LLVMNode): + __slots__ = "db type_ ref".split() + def __init__(self, db, type_): self.db = db assert isinstance(type_, lltype.FuncType) @@ -29,6 +31,8 @@ codewriter.funcdef(self.ref, returntype, inputargtypes) class FuncNode(ConstantLLVMNode): + __slots__ = "db value ref graph block_to_name".split() + def __init__(self, db, value): self.db = db self.value = value Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Mon Aug 29 23:12:38 2005 @@ -76,7 +76,7 @@ i = line.find(calltag) if i >= 0: cconv = 'ccc' - for funcname in funcnames.keys(): + for funcname in funcnames.iterkeys(): if line.find(funcname) >= 0: cconv = DEFAULT_CCONV break @@ -108,11 +108,36 @@ # for debug we create comments of every operation that may be executed self.debug = debug - def _add_to_database(self, name, funcptr): - ptr = getfunctionptr(self.translator, func) - c = inputconst(lltype.typeOf(funcptr), funcptr) - c.value._obj.graph.name = name - self.db.prepare_arg_value(c) + def _print_node_stats(self): + """run_pypy-llvm.sh [aug 29th 2005] + before slotifying: 350Mb + after slotifying: 300Mb, 35 minutes until the .ll file is fully written. + STATS (1, "") + STATS (1, "") + STATS (9, "") + STATS (46, "") + STATS (52, "") + STATS (189, "") + STATS (816, "") + STATS (1247, "") + STATS (1747, "") + STATS (5886, "") + STATS (24003, "") + STATS (25410, "") + STATS (26206, "") + STATS (268435, "") + """ + nodecount = {} + for node in self.db.getnodes(): + typ = type(node) + try: + nodecount[typ] += 1 + except: + nodecount[typ] = 1 + stats = [(count, str(typ)) for typ, count in nodecount.iteritems()] + stats.sort() + for s in stats: + print 'STATS', s def post_setup_externs(self): @@ -205,6 +230,9 @@ self.translator.rtyper.specialize_more_blocks() self.db.setup_all() + if self.debug: + self._print_node_stats() + if llcode_header is None: self.generate_llfile(extern_decls) lldeclarations, llimplementation = llcode_header, ll_functions Modified: pypy/dist/pypy/translator/llvm/node.py ============================================================================== --- pypy/dist/pypy/translator/llvm/node.py (original) +++ pypy/dist/pypy/translator/llvm/node.py Mon Aug 29 23:12:38 2005 @@ -1,6 +1,8 @@ from pypy.rpython import lltype class LLVMNode(object): + __slots__ = "".split() + nodename_count = {} def make_name(self, name): @@ -42,6 +44,7 @@ """ write function implementations. """ class ConstantLLVMNode(LLVMNode): + __slots__ = "".split() def get_ref(self): """ Returns a reference as used for operations in blocks. """ Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Mon Aug 29 23:12:38 2005 @@ -7,6 +7,8 @@ log = log.structnode class StructTypeNode(LLVMNode): + __slots__ = "db struct ref name".split() + def __init__(self, db, struct): assert isinstance(struct, lltype.Struct) self.db = db @@ -36,6 +38,7 @@ codewriter.structdef(self.ref, fields_types) class StructVarsizeTypeNode(StructTypeNode): + __slots__ = "constructor_ref constructor_decl".split() def __init__(self, db, struct): super(StructVarsizeTypeNode, self).__init__(db, struct) @@ -82,6 +85,8 @@ a struct, pointer to struct/array """ + __slots__ = "db value structtype ref".split() + def __init__(self, db, value): self.db = db self.value = value From cfbolz at codespeak.net Mon Aug 29 23:57:39 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 29 Aug 2005 23:57:39 +0200 (CEST) Subject: [pypy-svn] r17081 - pypy/dist/pypy/rpython/memory Message-ID: <20050829215739.62E0827B56@code1.codespeak.net> Author: cfbolz Date: Mon Aug 29 23:57:35 2005 New Revision: 17081 Modified: pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/gcwrapper.py Log: moving the construction of the GC object to gcwrapper. This makes sense, because the gcwrapper will be responsible for annotating the GC. Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Mon Aug 29 23:57:35 2005 @@ -9,7 +9,6 @@ from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr from pypy.rpython.memory.lltypesimulation import pyobjectptr, cast_ptr_to_int -from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter def notimplemented(*args, **kwargs): @@ -38,15 +37,8 @@ from pypy.rpython.memory.gc import MarkSweepGC, SemiSpaceGC use_gc = MarkSweepGC def create_mark_sweep_gc(llinterp, flowgraphs): - from pypy.rpython.memory.gcwrapper import GcWrapper, QueryTypes - # XXX there might me GCs that have headers that depend on the type - # therefore we have to change the query functions to annotatable ones later - qt = QueryTypes(llinterp) - gc = use_gc(4096, None, *qt.get_setup_query_functions()) - fgcc = FlowGraphConstantConverter(flowgraphs, gc, qt) - fgcc.convert() - gc.set_query_functions(*qt.create_query_functions()) - wrapper = GcWrapper(llinterp, gc, qt, fgcc.cvter.constantroots) + from pypy.rpython.memory.gcwrapper import GcWrapper + wrapper = GcWrapper(llinterp, flowgraphs, use_gc) return wrapper prepare_graphs_and_create_gc = create_no_gc Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Mon Aug 29 23:57:35 2005 @@ -5,6 +5,7 @@ from pypy.rpython.memory import lltypelayout from pypy.rpython.memory import lltypesimulation from pypy.rpython.memory import gc +from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter class QueryTypes(object): def __init__(self, llinterp): @@ -124,12 +125,19 @@ class GcWrapper(object): - def __init__(self, llinterp, gc, qt, constantroots): + def __init__(self, llinterp, flowgraphs, gc_class): + self.query_types = QueryTypes(llinterp) + # XXX there might me GCs that have headers that depend on the type + # therefore we have to change the query functions to annotatable ones + # later + self.gc = gc_class(4096, None, + *self.query_types.get_setup_query_functions()) + fgcc = FlowGraphConstantConverter(flowgraphs, self.gc, self.query_types) + fgcc.convert() + self.gc.set_query_functions(*self.query_types.create_query_functions()) self.llinterp = llinterp - self.gc = gc self.gc.get_roots = self.get_roots - self.query_types = qt - self.constantroots = constantroots + self.constantroots = fgcc.cvter.constantroots self.pseudo_root_pointers = NULL self.roots = [] From arigo at codespeak.net Tue Aug 30 15:58:47 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 15:58:47 +0200 (CEST) Subject: [pypy-svn] r17084 - pypy/dist/pypy/translator/c Message-ID: <20050830135847.C532727B61@code1.codespeak.net> Author: arigo Date: Tue Aug 30 15:58:46 2005 New Revision: 17084 Modified: pypy/dist/pypy/translator/c/gc.py Log: Use macros instead of repeating the code everywhere for incref/decref of objects, based on the idea that the C preprocessor is faster than our Python code producer and anyway having smaller .c files can't hurt. (Seems to save 10-20%.) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Aug 30 15:58:46 2005 @@ -88,18 +88,12 @@ def push_alive_nopyobj(self, expr, T): defnode = self.db.gettypedefnode(T.TO) if defnode.gcheader is not None: - return 'if (%s) %s->%s++;' % (expr, expr, defnode.gcheader) + return 'pypy_IncRf_%s(%s);' % (defnode.barename, expr) def pop_alive_nopyobj(self, expr, T): defnode = self.db.gettypedefnode(T.TO) if defnode.gcheader is not None: - dealloc = 'OP_FREE' - if defnode.gcinfo: - dealloc = defnode.gcinfo.deallocator or dealloc - return 'if (%s && !--%s->%s) %s(%s);' % (expr, expr, - defnode.gcheader, - dealloc, - expr) + return 'pypy_DecRf_%s(%s);' % (defnode.barename, expr) def push_alive_op_result(self, opname, expr, T): if opname !='direct_call' and T != PyObjPtr: @@ -144,6 +138,14 @@ gcinfo = defnode.gcinfo if gcinfo.deallocator: yield 'void %s(struct %s *);' % (gcinfo.deallocator, defnode.name) + if defnode.gcheader is not None: + dealloc = 'OP_FREE' + if defnode.gcinfo: + dealloc = defnode.gcinfo.deallocator or dealloc + yield '#define pypy_IncRf_%s(x) if (x) (x)->%s++' % ( + defnode.barename, defnode.gcheader,) + yield '#define pypy_DecRf_%s(x) if ((x) && !--(x)->%s) %s(x)' % ( + defnode.barename, defnode.gcheader, dealloc) def common_gcheader_initializationexpr(self, defnode): return 'REFCOUNT_IMMORTAL,' From arigo at codespeak.net Tue Aug 30 16:27:16 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 16:27:16 +0200 (CEST) Subject: [pypy-svn] r17085 - in pypy/dist/pypy/rpython: . test Message-ID: <20050830142716.4951027B61@code1.codespeak.net> Author: arigo Date: Tue Aug 30 16:27:13 2005 New Revision: 17085 Modified: pypy/dist/pypy/rpython/rclass.py pypy/dist/pypy/rpython/test/test_rclass.py Log: We use in descroperation.py "if type(descr) is Function" where 'descr' can sometimes be None. This would crash after translation. Added a test and, for now, let the low-level type() of a NULL instance return a NULL pointer. --This line, and those below, will be ignored-- M rpython/test/test_rclass.py M rpython/rclass.py Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Tue Aug 30 16:27:13 2005 @@ -558,8 +558,12 @@ return vptr def rtype_type(self, hop): - vinst, = hop.inputargs(self) - return self.getfield(vinst, '__class__', hop.llops) + instance_repr = self.common_repr() + vinst, = hop.inputargs(instance_repr) + if hop.args_s[0].can_be_none(): + return hop.gendirectcall(ll_inst_type, vinst) + else: + return instance_repr.getfield(vinst, '__class__', hop.llops) def rtype_hash(self, hop): if self.classdef is None: @@ -700,3 +704,10 @@ if cached == 0: cached = ins.hash_cache = id(ins) return cached + +def ll_inst_type(obj): + if obj: + return obj.typeptr + else: + # type(None) -> NULL (for now) + return nullptr(typeOf(obj).TO.typeptr.TO) Modified: pypy/dist/pypy/rpython/test/test_rclass.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rclass.py (original) +++ pypy/dist/pypy/rpython/test/test_rclass.py Tue Aug 30 16:27:13 2005 @@ -300,3 +300,24 @@ assert res.item0 == True assert res.item1 == intmask(hash(c)+hash(d)) +def test_type(): + class A: + pass + class B(A): + pass + def g(a): + return type(a) + def f(i): + if i > 0: + a = A() + elif i < 0: + a = B() + else: + a = None + return g(a) is A # should type(None) work? returns None for now + res = interpret(f, [1]) + assert res is True + res = interpret(f, [-1]) + assert res is False + res = interpret(f, [0]) + assert res is False From arigo at codespeak.net Tue Aug 30 17:08:58 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 17:08:58 +0200 (CEST) Subject: [pypy-svn] r17086 - in pypy/dist/pypy: interpreter objspace Message-ID: <20050830150858.7DBB527B5E@code1.codespeak.net> Author: arigo Date: Tue Aug 30 17:08:54 2005 New Revision: 17086 Modified: pypy/dist/pypy/interpreter/eval.py pypy/dist/pypy/interpreter/gateway.py pypy/dist/pypy/objspace/descroperation.py Log: Enormous speed increase following discussion with Samuele about how incredibly indirect something like a space.add() between two integers actually is. This introduces a rather isolated shortcut, which even makes sense when reading the source of descroperation.py, where the non-shortcut case of space.get_and_call_function() can be seen as a fall-back for the uncommon general case. Modified: pypy/dist/pypy/interpreter/eval.py ============================================================================== --- pypy/dist/pypy/interpreter/eval.py (original) +++ pypy/dist/pypy/interpreter/eval.py Tue Aug 30 17:08:54 2005 @@ -50,6 +50,10 @@ def getdocstring(self): return None + fastcall_1 = None + fastcall_2 = None + fastcall_3 = None + class Frame(Wrappable): """A frame is an environment supporting the execution of a code object. Abstract base class.""" Modified: pypy/dist/pypy/interpreter/gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/gateway.py (original) +++ pypy/dist/pypy/interpreter/gateway.py Tue Aug 30 17:08:54 2005 @@ -396,6 +396,17 @@ self.framecls = make_builtin_frame_class(func, orig_sig, unwrap_spec) + # speed hack + if unwrap_spec == [ObjSpace, W_Root]: + self.__class__ = BuiltinCode1 + self.fastfunc_1 = func + elif unwrap_spec == [ObjSpace, W_Root, W_Root]: + self.__class__ = BuiltinCode2 + self.fastfunc_2 = func + elif unwrap_spec == [ObjSpace, W_Root, W_Root, W_Root]: + self.__class__ = BuiltinCode3 + self.fastfunc_3 = func + def create_frame(self, space, w_globals, closure=None): return self.framecls(space, self, w_globals) @@ -405,6 +416,18 @@ def getdocstring(self): return self.docstring +class BuiltinCode1(BuiltinCode): + def fastcall_1(self, space, w1): + return self.fastfunc_1(space, w1) + +class BuiltinCode2(BuiltinCode): + def fastcall_2(self, space, w1, w2): + return self.fastfunc_2(space, w1, w2) + +class BuiltinCode3(BuiltinCode): + def fastcall_3(self, space, w1, w2, w3): + return self.fastfunc_3(space, w1, w2, w3) + class interp2app(Wrappable): """Build a gateway that calls 'f' at interp-level.""" Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Tue Aug 30 17:08:54 2005 @@ -80,8 +80,29 @@ return space.call_args(w_impl, args) def get_and_call_function(space, w_descr, w_obj, *args_w): - args = Arguments(space, list(args_w)) - return space.get_and_call_args(w_descr, w_obj, args) + descr = space.interpclass_w(w_descr) + # a special case for performance and to avoid infinite recursion + if type(descr) is Function: + # the fastcall paths are purely for performance, but the resulting + # increase of speed is huge + if len(args_w) == 0: + fastcall_1 = descr.code.fastcall_1 + if fastcall_1: + return fastcall_1(space, w_obj) + elif len(args_w) == 1: + fastcall_2 = descr.code.fastcall_2 + if fastcall_2: + return fastcall_2(space, w_obj, args_w[0]) + elif len(args_w) == 2: + fastcall_3 = descr.code.fastcall_3 + if fastcall_3: + return fastcall_3(space, w_obj, args_w[0], args_w[1]) + args = Arguments(space, list(args_w)) + return descr.call_args(args.prepend(w_obj)) + else: + args = Arguments(space, list(args_w)) + w_impl = space.get(w_descr, w_obj) + return space.call_args(w_impl, args) def call_args(space, w_obj, args): # a special case for performance From cfbolz at codespeak.net Tue Aug 30 17:26:19 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 30 Aug 2005 17:26:19 +0200 (CEST) Subject: [pypy-svn] r17088 - pypy/dist/pypy/rpython/memory Message-ID: <20050830152619.8D9D427B61@code1.codespeak.net> Author: cfbolz Date: Tue Aug 30 17:26:18 2005 New Revision: 17088 Modified: pypy/dist/pypy/rpython/memory/gclltype.py Log: arggglll. Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Tue Aug 30 17:26:18 2005 @@ -4,7 +4,7 @@ from pypy.rpython.lltype import GC_CONTAINER from pypy.rpython.lltype import Signed, Unsigned, Float, Char, Bool, Void from pypy.rpython.lltype import UniChar, Ptr, typeOf, InvalidCast - +from pypy.rpython.memory.convertlltype import FlowGraphConstantConverter from pypy.rpython.memory.lltypesimulation import cast_pointer, free from pypy.rpython.memory.lltypesimulation import simulatorptr as _ptr from pypy.rpython.memory.lltypesimulation import malloc, functionptr, nullptr From arigo at codespeak.net Tue Aug 30 17:56:34 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 17:56:34 +0200 (CEST) Subject: [pypy-svn] r17089 - pypy/dist/pypy/translator/c/src Message-ID: <20050830155634.8113327B6D@code1.codespeak.net> Author: arigo Date: Tue Aug 30 17:56:32 2005 New Revision: 17089 Modified: pypy/dist/pypy/translator/c/src/main.h Log: Catch interp-level exceptions in main.h and display them as "fatal errors" (we can only easily display their type, at the moment). This used to just return -1 as the exit code, which the OS interprets strangely. Modified: pypy/dist/pypy/translator/c/src/main.h ============================================================================== --- pypy/dist/pypy/translator/c/src/main.h (original) +++ pypy/dist/pypy/translator/c/src/main.h Tue Aug 30 17:56:32 2005 @@ -7,7 +7,7 @@ int main(int argc, char *argv[]) { char *errmsg = "out of memory"; - int i; + int i, exitcode; RPyListOfString *list; errmsg = RPython_StartupCode(); if (errmsg) goto error; @@ -20,8 +20,14 @@ _RPyListOfString_SetItem(list, i, s); } - - return STANDALONE_ENTRY_POINT(list); + exitcode = STANDALONE_ENTRY_POINT(list); + if (RPyExceptionOccurred()) { + /* fish for the exception type, at least */ + fprintf(stderr, "Fatal PyPy error: %s\n", + rpython_exc_type->ov_name->items); + exitcode = 1; + } + return exitcode; error: fprintf(stderr, "Fatal error during initialization: %s\n", errmsg); From ale at codespeak.net Tue Aug 30 18:02:17 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 30 Aug 2005 18:02:17 +0200 (CEST) Subject: [pypy-svn] r17090 - pypy/dist/pypy/module/_codecs/test Message-ID: <20050830160217.56AF427B6D@code1.codespeak.net> Author: ale Date: Tue Aug 30 18:02:16 2005 New Revision: 17090 Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py Log: added one more test for named unicode characters Added a test for unicode literals Modified: pypy/dist/pypy/module/_codecs/test/test_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/test/test_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/test/test_codecs.py Tue Aug 30 18:02:16 2005 @@ -34,6 +34,10 @@ raises( UnicodeDecodeError, unicode,'\\N{SpaCE}','unicode-escape') assert unicode('\\N{SPACE}\\N{SPACE}','unicode-escape') == u" " assert unicode('\\N{SPACE}a\\N{SPACE}','unicode-escape') == u" a " + assert "\\N{foo}xx".decode("unicode-escape", "ignore") == u"xx" + + def test_literals(self): + raises(UnicodeError, eval, 'u\'\\Uffffffff\'') def test_insecure_pickle(self): import pickle From arigo at codespeak.net Tue Aug 30 18:05:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 18:05:46 +0200 (CEST) Subject: [pypy-svn] r17091 - pypy/dist/pypy/interpreter Message-ID: <20050830160546.3B0B927B6D@code1.codespeak.net> Author: arigo Date: Tue Aug 30 18:05:44 2005 New Revision: 17091 Modified: pypy/dist/pypy/interpreter/pyopcode.py Log: Don't send f.w_locals to the space.is_() operation if it is None. (Bug discovered by running the thunk object space, which crashes on unexpected Nones) Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Tue Aug 30 18:05:44 2005 @@ -357,7 +357,8 @@ f.space.gettypeobject(PyCode.typedef)) w_prog, w_globals, w_locals = f.space.unpacktuple(w_resulttuple, 3) - plain = f.space.is_true(f.space.is_(w_locals, f.w_locals)) + plain = (f.w_locals is not None and + f.space.is_true(f.space.is_(w_locals, f.w_locals))) if plain: w_locals = f.getdictscope() pycode = f.space.interpclass_w(w_prog) From arigo at codespeak.net Tue Aug 30 18:35:42 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 18:35:42 +0200 (CEST) Subject: [pypy-svn] r17092 - pypy/dist/pypy/rpython Message-ID: <20050830163542.16B0B27B6D@code1.codespeak.net> Author: arigo Date: Tue Aug 30 18:35:39 2005 New Revision: 17092 Modified: pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rstr.py Log: A bug left over from the addition of the 'length' field in rlists, caused by code that allocated the GcStructs of a list by hand in rstr.py. Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Tue Aug 30 18:35:39 2005 @@ -18,6 +18,7 @@ # Concrete implementation of RPython lists: # # struct list { +# int length; # items_array *items; # } # Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Tue Aug 30 18:35:39 2005 @@ -886,6 +886,7 @@ return newstr def ll_split_chr(LISTPTR, s, c): + from pypy.rpython.rlist import ll_newlist chars = s.chars strlen = len(chars) count = 1 @@ -894,8 +895,8 @@ if chars[i] == c: count += 1 i += 1 - res = malloc(LISTPTR.TO) - items = res.items = malloc(LISTPTR.TO.items.TO, count) + res = ll_newlist(LISTPTR, count) + items = res.items i = 0 j = 0 From arigo at codespeak.net Tue Aug 30 19:09:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 19:09:23 +0200 (CEST) Subject: [pypy-svn] r17094 - in pypy/dist/pypy: interpreter objspace Message-ID: <20050830170923.7570B27B6D@code1.codespeak.net> Author: arigo Date: Tue Aug 30 19:09:21 2005 New Revision: 17094 Modified: pypy/dist/pypy/interpreter/eval.py pypy/dist/pypy/objspace/descroperation.py Log: A variant of the fastcall() shortcuts that are less Pythonic :-( no storing of None in the class to mean "this method is missing". Makes the rtyper unhappy at the moment, and it's messy to translate to non-C targets in general. Modified: pypy/dist/pypy/interpreter/eval.py ============================================================================== --- pypy/dist/pypy/interpreter/eval.py (original) +++ pypy/dist/pypy/interpreter/eval.py Tue Aug 30 19:09:21 2005 @@ -50,9 +50,13 @@ def getdocstring(self): return None - fastcall_1 = None - fastcall_2 = None - fastcall_3 = None + # a performance hack (see gateway.BuiltinCode1/2/3) + def fastcall_1(self, space, w1): + return None + def fastcall_2(self, space, w1, w2): + return None + def fastcall_3(self, space, w1, w2, w3): + return None class Frame(Wrappable): """A frame is an environment supporting the execution of a code object. Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Tue Aug 30 19:09:21 2005 @@ -86,17 +86,18 @@ # the fastcall paths are purely for performance, but the resulting # increase of speed is huge if len(args_w) == 0: - fastcall_1 = descr.code.fastcall_1 - if fastcall_1: - return fastcall_1(space, w_obj) + w_res = descr.code.fastcall_1(space, w_obj) + if w_res is not None: + return w_res elif len(args_w) == 1: - fastcall_2 = descr.code.fastcall_2 - if fastcall_2: - return fastcall_2(space, w_obj, args_w[0]) + w_res = descr.code.fastcall_2(space, w_obj, args_w[0]) + if w_res is not None: + return w_res elif len(args_w) == 2: - fastcall_3 = descr.code.fastcall_3 - if fastcall_3: - return fastcall_3(space, w_obj, args_w[0], args_w[1]) + w_res = descr.code.fastcall_3(space, w_obj, args_w[0], + args_w[1]) + if w_res is not None: + return w_res args = Arguments(space, list(args_w)) return descr.call_args(args.prepend(w_obj)) else: From cfbolz at codespeak.net Tue Aug 30 19:18:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 30 Aug 2005 19:18:16 +0200 (CEST) Subject: [pypy-svn] r17095 - in pypy/dist/pypy/rpython: . memory memory/test Message-ID: <20050830171816.A0B0627B70@code1.codespeak.net> Author: cfbolz Date: Tue Aug 30 19:18:15 2005 New Revision: 17095 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: added deferred refcounting implementation + tests (failing) this is an intermediate checkin because I have to change computers. Sorry for the mess. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Aug 30 19:18:15 2005 @@ -247,7 +247,13 @@ # obj should be pointer FIELDTYPE = getattr(self.llt.typeOf(obj).TO, fieldname) if FIELDTYPE != self.llt.Void: - setattr(obj, fieldname, fieldvalue) + gc = self.llinterpreter.gc + if gc is None or not gc.needs_write_barrier(FIELDTYPE): + setattr(obj, fieldname, fieldvalue) + else: + args = gc.get_arg_write_barrier(obj, fieldname, fieldvalue) + write_barrier = gc.get_funcptr_write_barrier() + result = self.op_direct_call(write_barrier, *args) def op_getarrayitem(self, array, index): return array[index] @@ -256,7 +262,13 @@ # array should be a pointer ITEMTYPE = self.llt.typeOf(array).TO.OF if ITEMTYPE != self.llt.Void: - array[index] = item + gc = self.llinterpreter.gc + if gc is None or not gc.needs_write_barrier(ITEMTYPE): + array[index] = item + else: + args = gc.get_arg_write_barrier(array, index, item) + write_barrier = gc.get_funcptr_write_barrier() + self.op_direct_call(write_barrier, *args) def op_direct_call(self, f, *args): has_callable = getattr(f._obj, '_callable', None) is not None Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Tue Aug 30 19:18:15 2005 @@ -1,5 +1,5 @@ from pypy.rpython.memory.lladdress import raw_malloc, raw_free, raw_memcopy -from pypy.rpython.memory.lladdress import NULL, address +from pypy.rpython.memory.lladdress import NULL, address, Address from pypy.rpython.memory.support import AddressLinkedList from pypy.rpython.memory import lltypesimulation from pypy.rpython import lltype @@ -21,6 +21,7 @@ gc_interface = { "malloc": lltype.FuncType((lltype.Signed, lltype.Signed), lltype.Signed), "collect": lltype.FuncType((), lltype.Void), + "write_barrier": lltype.FuncType((Address, ) * 3, lltype.Void), } def dummy_get_roots(): @@ -42,25 +43,19 @@ self.varsize_offset_to_length = varsize_offset_to_length self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part + def write_barrier(self, addr, addr_to, addr_struct): + addr_to.address[0] = addr + class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" - def __init__(self, start_heap_size, get_roots, is_varsize, - offsets_to_gc_pointers, fixed_size, varsize_item_sizes, - varsize_offset_to_variable_part, varsize_offset_to_length, - varsize_offsets_to_gcpointers_in_var_part): + def __init__(self, start_heap_size=4096, get_roots=None): self.bytes_malloced = 0 self.heap_size = start_heap_size #need to maintain a list of malloced objects, since we used the systems #allocator and can't walk the heap self.malloced_objects = AddressLinkedList() - self.is_varsize = is_varsize - self.offsets_to_gc_pointers = offsets_to_gc_pointers - self.fixed_size = fixed_size - self.varsize_item_sizes = varsize_item_sizes - self.varsize_offset_to_variable_part = varsize_offset_to_variable_part - self.varsize_offset_to_length = varsize_offset_to_length - self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part + self.set_query_functions(None, None, None, None, None, None, None) self.get_roots = get_roots def malloc(self, typeid, length=0): @@ -154,23 +149,14 @@ class SemiSpaceGC(GCBase): _alloc_flavor_ = "raw" - def __init__(self, space_size, get_roots, is_varsize, - offsets_to_gc_pointers, fixed_size, varsize_item_sizes, - varsize_offset_to_variable_part, varsize_offset_to_length, - varsize_offsets_to_gcpointers_in_var_part): + def __init__(self, space_size=4096, get_roots=None): self.bytes_malloced = 0 self.space_size = space_size self.tospace = raw_malloc(space_size) self.top_of_space = self.tospace + space_size self.fromspace = raw_malloc(space_size) self.free = self.tospace - self.is_varsize = is_varsize - self.offsets_to_gc_pointers = offsets_to_gc_pointers - self.fixed_size = fixed_size - self.varsize_item_sizes = varsize_item_sizes - self.varsize_offset_to_variable_part = varsize_offset_to_variable_part - self.varsize_offset_to_length = varsize_offset_to_length - self.varsize_offsets_to_gcpointers_in_var_part = varsize_offsets_to_gcpointers_in_var_part + self.set_query_functions(None, None, None, None, None, None, None) self.get_roots = get_roots def malloc(self, typeid, length=0): @@ -279,3 +265,100 @@ def init_gc_object(self, addr, typeid): addr.signed[0] = 0 addr.signed[1] = typeid + + +class DeferredRefcountingGC(GCBase): + _alloc_flavor_ = "raw" + + def __init__(self, max_refcount_zero=10, get_roots=None): + self.zero_ref_counts = AddressLinkedList() + self.length_zero_ref_counts = 0 + self.max_refcount_zero = max_refcount_zero + self.set_query_functions(None, None, None, None, None, None, None) + self.get_roots = get_roots + + def malloc(self, typeid, length=0): + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + size += length * self.varsize_item_sizes(typeid) + size_gc_header = self.size_gc_header() + result = raw_malloc(size + size_gc_header) + print "mallocing %s, size %s at %s" % (typeid, size, result) + self.init_gc_object(result, typeid) + return result + size_gc_header + + def collect(self): + roots = self.get_roots() + while 1: + root = roots.pop() + if root == NULL: + break + print "root", root, root.address[0] + self.incref(root.address[0]) + while 1: + candidate = self.zero_ref_counts.pop() + self.length_zero_ref_counts -= 1 + if candidate == NULL: + break + refcount = self.refcount(candidate) + if refcount == 0: + self.deallocate(candidate) + roots = self.get_roots() + while 1: + root = roots.pop() + if root == NULL: + break + print "root", root, root.address[0] + self.decref(root.address[0]) + + def write_barrier(self, addr, addr_to, addr_struct): + self.decref(addr_to.address[0]) + addr_to.address[0] = addr + self.incref(addr) + + def deallocate(self, addr): + gc_info = obj - self.size_gc_header() + typeid = gc_info.signed[1] + print "deallocating", obj, typeid + offsets = self.offsets_to_gc_pointers(typeid) + for i in range(len(offsets)): + pointer = obj + offsets[i] + self.decref(pointer.address[0]) + if self.is_varsize(typeid): + offset = self.varsize_offset_to_variable_part( + typeid) + length = (obj + self.varsize_offset_to_length(typeid)).signed[0] + offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid) + itemlength = self.varsize_item_sizes(typeid) + for i in range(length): + item = obj + offset + itemlength * i + for j in range(len(offsets)): + pointer = item + offsets[j] + self.decref(pointer.address[0]) + raw_free(addr) + + def incref(self, addr): + (addr - self.size_gc_header()).signed[0] += 1 + + def decref(self, addr): + if addr == NULL: + return + refcount = (addr - self.size_gc_header()).signed[0] + if refcount == 1: + self.zero_ref_counts.append(addr) + self.length_zero_ref_counts += 1 + if self.length_zero_ref_counts > self.max_refcount_zero: + self.collect() + (addr - self.size_gc_header()).signed[0] = refcount - 1 + assert refcount > 0 + + def refcount(self, addr): + (addr - self.size_gc_header()).signed[0] + + def init_gc_object(self, addr, typeid): + addr.signed[0] = 0 # refcount + addr.signed[1] = typeid + + def size_gc_header(self, typeid=0): + return int_size * 2 + Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Tue Aug 30 19:18:15 2005 @@ -130,8 +130,8 @@ # XXX there might me GCs that have headers that depend on the type # therefore we have to change the query functions to annotatable ones # later - self.gc = gc_class(4096, None, - *self.query_types.get_setup_query_functions()) + self.gc = gc_class() + self.gc.set_query_functions(*self.query_types.get_setup_query_functions()) fgcc = FlowGraphConstantConverter(flowgraphs, self.gc, self.query_types) fgcc.convert() self.gc.set_query_functions(*self.query_types.create_query_functions()) @@ -141,6 +141,7 @@ self.pseudo_root_pointers = NULL self.roots = [] + def get_arg_malloc(self, TYPE, size=0): typeid = self.query_types.get_typeid(TYPE) return [typeid, size] @@ -154,6 +155,32 @@ self.update_changed_addresses() return result + + def needs_write_barrier(self, TYPE): + return (hasattr(self.gc, "write_barrier") and + isinstance(TYPE, lltype.Ptr) and + isinstance(TYPE.TO, (lltype.GcStruct, lltype.GcArray))) + + def get_arg_write_barrier(self, obj, index_or_field, item): + #XXX: quick hack to get the correct addresses, fix later + layout = lltypelayout.get_layout(lltype.typeOf(obj).TO) + if isinstance(lltype.typeOf(obj).TO, lltype.Array): + assert isinstance(index_or_field, int) + offset = layout[0] + layout[1] * index_or_field + addr_to = obj._address + layout[0] + index_or_field * layout[1] + return item._address, addr_to, obj._address + else: + offset = layout[index_or_field] + addr_to = obj._address + offset + return item._address, addr_to, obj._address + + + def get_funcptr_write_barrier(self): + return self.llinterp.llt.functionptr(gc.gc_interface["write_barrier"], + "write_barrier", + _callable=self.gc.write_barrier) + + def update_changed_addresses(self): for i, root in enumerate(self.roots): if root._address != self.pseudo_root_pointers.address[i]: Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Tue Aug 30 19:18:15 2005 @@ -4,6 +4,7 @@ from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.memory.gc import GCError, MarkSweepGC, SemiSpaceGC +from pypy.rpython.memory.gc import DeferredRefcountingGC from pypy.rpython.memory.support import AddressLinkedList, INT_SIZE from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL from pypy.rpython.memory.simulator import MemorySimulatorError @@ -136,7 +137,7 @@ res = interpret(append_to_list, [i, i - 1]) assert res == i - 1 # crashes if constants are not considered roots - def DONOTtest_string_concatenation(self): + def test_string_concatenation(self): curr = simulator.current_size def concat(j): lst = [] @@ -252,3 +253,52 @@ res = interpret(concat, [100]) assert res == concat(100) assert simulator.current_size - curr < 16000 + +class DONOTTestDeferredRefcountingGC(object): + def setup_class(cls): + gclltype.use_gc = DeferredRefcountingGC + cls.old = gclltype.use_gc + def teardown_class(cls): + gclltype.use_gc = cls.old + + def test_llinterp_lists(self): + curr = simulator.current_size + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = [1] * 10 + j = 0 + while j < 20: + j += 1 + a.append(j) + res = interpret(malloc_a_lot, []) + assert simulator.current_size - curr < 16000 + print "size before: %s, size after %s" % (curr, simulator.current_size) + + def test_llinterp_tuples(self): + curr = simulator.current_size + def malloc_a_lot(): + i = 0 + while i < 10: + i += 1 + a = (1, 2, i) + b = [a] * 10 + j = 0 + while j < 20: + j += 1 + b.append((1, j, i)) + res = interpret(malloc_a_lot, []) + assert simulator.current_size - curr < 16000 + print "size before: %s, size after %s" % (curr, simulator.current_size) + + def test_global_list(self): + lst = [] + def append_to_list(i, j): + lst.append([i] * 500) + return lst[j][0] + res = interpret(append_to_list, [0, 0]) + assert res == 0 + for i in range(1, 15): + res = interpret(append_to_list, [i, i - 1]) + assert res == i - 1 # crashes if constants are not considered roots From arigo at codespeak.net Tue Aug 30 19:34:13 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 19:34:13 +0200 (CEST) Subject: [pypy-svn] r17096 - pypy/dist/pypy/interpreter Message-ID: <20050830173413.4F20627B69@code1.codespeak.net> Author: arigo Date: Tue Aug 30 19:34:12 2005 New Revision: 17096 Modified: pypy/dist/pypy/interpreter/gateway.py Log: Two bug fixes in BuiltinCode1,2,3 to make them behave like BuiltinFrame.run(): * they must convert None to space.w_None * they must catch the async exceptions Modified: pypy/dist/pypy/interpreter/gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/gateway.py (original) +++ pypy/dist/pypy/interpreter/gateway.py Tue Aug 30 19:34:12 2005 @@ -416,17 +416,54 @@ def getdocstring(self): return self.docstring + +# (verbose) performance hack below + class BuiltinCode1(BuiltinCode): def fastcall_1(self, space, w1): - return self.fastfunc_1(space, 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 RuntimeError, e: + raise OperationError(space.w_RuntimeError, + space.wrap("internal error: " + str(e))) + if w_result is None: + w_result = space.w_None + return w_result class BuiltinCode2(BuiltinCode): def fastcall_2(self, space, w1, w2): - return self.fastfunc_2(space, 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 RuntimeError, e: + raise OperationError(space.w_RuntimeError, + space.wrap("internal error: " + str(e))) + if w_result is None: + w_result = space.w_None + return w_result class BuiltinCode3(BuiltinCode): def fastcall_3(self, space, w1, w2, w3): - return self.fastfunc_3(space, 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 RuntimeError, e: + raise OperationError(space.w_RuntimeError, + space.wrap("internal error: " + str(e))) + if w_result is None: + w_result = space.w_None + return w_result + class interp2app(Wrappable): """Build a gateway that calls 'f' at interp-level.""" From arigo at codespeak.net Tue Aug 30 20:02:57 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 20:02:57 +0200 (CEST) Subject: [pypy-svn] r17098 - in pypy/dist/pypy: . module/thread/test Message-ID: <20050830180257.62E4227B6D@code1.codespeak.net> Author: arigo Date: Tue Aug 30 20:02:54 2005 New Revision: 17098 Modified: pypy/dist/pypy/conftest.py pypy/dist/pypy/module/thread/test/support.py Log: Some tentative clean-ups of conftest.py w.r.t. object space creation and caching. Now the gettestobjspace() function takes an optional name 'std'/'thunk' as before, but also keyword options to pass to the space. The result is cached. As far as I can tell there was already no difference left between getobjspace() and gettestobjspace(). For interp-level test classes, 'cls.space' attribute is now lazily computed the first time the attribute is actually accessed. This is cool when working on parts of PyPy that don't need an object space around, or that only need a custom one (e.g. with a usemodules keyword). Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Tue Aug 30 20:02:54 2005 @@ -38,22 +38,26 @@ help="(mixed) modules to use."), ) -def getobjspace(name=None, _spacecache={}): +_SPACECACHE={} +def getobjspace(name=None, **kwds): """ helper for instantiating and caching space's for testing. """ - name = name or option.objspace or 'std' + name = name or option.objspace or 'std' + key = kwds.items() + key.sort() + key = name, tuple(key) try: - return _spacecache[name] + return _SPACECACHE[key] except KeyError: assert name in ('std', 'thunk'), name mod = __import__('pypy.objspace.%s' % name, None, None, ['Space']) Space = mod.Space try: - space = Space(uselibfile=option.uselibfile, - nofaking=option.nofaking, - oldstyle=option.oldstyle, - usemodules=option.usemodules - ) + kwds.setdefault('uselibfile', option.uselibfile) + kwds.setdefault('nofaking', option.nofaking) + kwds.setdefault('oldstyle', option.oldstyle) + kwds.setdefault('usemodules', option.usemodules) + space = Space(**kwds) except KeyboardInterrupt: raise except OperationError, e: @@ -68,7 +72,7 @@ import traceback traceback.print_exc() py.test.fail("fatal: cannot initialize objspace: %r" %(Space,)) - _spacecache[name] = space + _SPACECACHE[key] = space space.setitem(space.builtin.w_dict, space.wrap('AssertionError'), appsupport.build_pytest_assertion(space)) space.setitem(space.builtin.w_dict, space.wrap('raises'), @@ -117,12 +121,19 @@ else: return IntTestFunction(name, parent=self) -def gettestobjspace(name=None): - space = getobjspace(name) - if space is None: - py.test.skip('test requires object space %r' % (name,)) +def gettestobjspace(name=None, **kwds): + space = getobjspace(name, **kwds) + #if space is None: XXX getobjspace() cannot return None any more I think + # py.test.skip('test requires object space %r' % (name,)) return space +class LazyObjSpaceGetter(object): + def __get__(self, obj, cls=None): + space = gettestobjspace() + if cls: + cls.space = space + return space + class PyPyTestFunction(py.test.Function): # All PyPy test items catch and display OperationErrors specially. @@ -187,7 +198,7 @@ def setup(self): cls = self.obj - cls.space = gettestobjspace() + cls.space = LazyObjSpaceGetter() super(IntClassCollector, self).setup() class AppClassInstance(py.test.collect.Instance): Modified: pypy/dist/pypy/module/thread/test/support.py ============================================================================== --- pypy/dist/pypy/module/thread/test/support.py (original) +++ pypy/dist/pypy/module/thread/test/support.py Tue Aug 30 20:02:54 2005 @@ -1,11 +1,11 @@ import py +from pypy.conftest import gettestobjspace class GenericTestThread: def setup_class(cls): - space = cls.space - if "thread" not in space.options.usemodules: - py.test.skip("--usemodules=thread option not provided") + space = gettestobjspace(usemodules=('thread',)) + cls.space = space cls.w_waitfor = space.appexec([], """(): import time From arigo at codespeak.net Tue Aug 30 20:23:52 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 30 Aug 2005 20:23:52 +0200 (CEST) Subject: [pypy-svn] r17099 - in pypy/dist/pypy: interpreter objspace Message-ID: <20050830182352.0786527B6D@code1.codespeak.net> Author: arigo Date: Tue Aug 30 20:23:50 2005 New Revision: 17099 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/interactive.py pypy/dist/pypy/objspace/proxy.py Log: 'sys.pypy_objspaceclass' was broken. The proper fix is to not let the thunk objspace store a modified __repr__ in the space instance -- that won't work with repr(). Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Tue Aug 30 20:23:50 2005 @@ -143,7 +143,10 @@ pass def __repr__(self): - return self.__class__.__name__ + try: + return self._this_space_repr_ + except AttributeError: + return self.__class__.__name__ def setbuiltinmodule(self, importname, installed_builtin_modules=[]): """NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules""" Modified: pypy/dist/pypy/interpreter/interactive.py ============================================================================== --- pypy/dist/pypy/interpreter/interactive.py (original) +++ pypy/dist/pypy/interpreter/interactive.py Tue Aug 30 20:23:50 2005 @@ -129,8 +129,8 @@ w_sys = self.space.sys major, minor, micro, _, _ = self.space.unwrap(self.space.sys.get('pypy_version_info')) elapsed = time.time() - self.space._starttime - banner = "PyPy %d.%d.%d in %s on top of Python %s (startupttime: %.2f secs)" % ( - major, minor, micro ,self.space.__repr__(), sys.version.split()[0], elapsed) + banner = "PyPy %d.%d.%d in %r on top of Python %s (startupttime: %.2f secs)" % ( + major, minor, micro, self.space, sys.version.split()[0], elapsed) code.InteractiveConsole.interact(self, banner) def raw_input(self, prompt=""): Modified: pypy/dist/pypy/objspace/proxy.py ============================================================================== --- pypy/dist/pypy/objspace/proxy.py (original) +++ pypy/dist/pypy/objspace/proxy.py Tue Aug 30 20:23:50 2005 @@ -17,7 +17,7 @@ if proxy: setattr(space, name, proxy) - prevrepr = space.__repr__() - space.__repr__ = lambda: '%s(%s)' % (proxyname, prevrepr) + prevrepr = repr(space) + space._this_space_repr_ = '%s(%s)' % (proxyname, prevrepr) # __________________________________________________________________________ From xoraxax at codespeak.net Tue Aug 30 20:51:45 2005 From: xoraxax at codespeak.net (xoraxax at codespeak.net) Date: Tue, 30 Aug 2005 20:51:45 +0200 (CEST) Subject: [pypy-svn] r17101 - pypy/dist/pypy/doc Message-ID: <20050830185145.1032327B70@code1.codespeak.net> Author: xoraxax Date: Tue Aug 30 20:51:44 2005 New Revision: 17101 Modified: pypy/dist/pypy/doc/getting-started.txt Log: Fixed typo. Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Tue Aug 30 20:51:44 2005 @@ -381,7 +381,7 @@ functionality. Calling compiled LLVM code from CPython is more restrictive than the C backend - the return type and the arguments of the entry function must be ints, floats or bools. The emphasis of the LLVM backend is to compile -standalone executables - please see the pypy/translate/llvm/demo directory for +standalone executables - please see the pypy/translator/llvm/demo directory for examples. Here is a simple example to try:: From cfbolz at codespeak.net Tue Aug 30 21:37:32 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 30 Aug 2005 21:37:32 +0200 (CEST) Subject: [pypy-svn] r17103 - pypy/dist/pypy/rpython/memory Message-ID: <20050830193732.CF99727B73@code1.codespeak.net> Author: cfbolz Date: Tue Aug 30 21:37:29 2005 New Revision: 17103 Modified: pypy/dist/pypy/rpython/memory/gc.py Log: working on running the GCs on the llinterpreter: - removing for loops, because they allocate :-( - change dummy_annotate so that the annotator does not think it is a constant Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Tue Aug 30 21:37:29 2005 @@ -12,6 +12,8 @@ def get_dummy_annotate(gc): def dummy_annotate(): + gc.get_roots = dummy_get_roots1 #prevent the get_roots attribute to + gc.get_roots = dummy_get_roots2 #be constants a = gc.malloc(1, 2) b = gc.malloc(2, 3) gc.collect() @@ -24,8 +26,18 @@ "write_barrier": lltype.FuncType((Address, ) * 3, lltype.Void), } -def dummy_get_roots(): - return [NULL, raw_malloc(10)] #just random addresses +def dummy_get_roots1(): + ll = AddressLinkedList() + ll.append(NULL) + ll.append(raw_malloc(10)) + return ll + +def dummy_get_roots2(): + ll = AddressLinkedList() + ll.append(raw_malloc(10)) + ll.append(NULL) + return ll + class GCBase(object): _alloc_flavor_ = "raw" @@ -98,9 +110,11 @@ continue typeid = gc_info.signed[1] offsets = self.offsets_to_gc_pointers(typeid) - for i in range(len(offsets)): + i = 0 + while i < len(offsets): pointer = curr + offsets[i] objects.append(pointer.address[0]) + i += 1 if self.is_varsize(typeid): offset = self.varsize_offset_to_variable_part( typeid) @@ -108,10 +122,14 @@ offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid) itemlength = self.varsize_item_sizes(typeid) curr += offset - for i in range(length): + i = 0 + while i < length: item = curr + itemlength * i - for j in range(len(offsets)): + j = 0 + while j < len(offsets): objects.append((item + offsets[j]).address[0]) + j += 1 + i += 1 gc_info.signed[0] = 1 newmo = AddressLinkedList() curr_heap_size = 0 @@ -221,22 +239,28 @@ typeid = gc_info.signed[1] ## print "scanning", obj, typeid offsets = self.offsets_to_gc_pointers(typeid) - for i in range(len(offsets)): + i = 0 + while i < len(offsets): pointer = obj + offsets[i] if pointer.address[0] != NULL: pointer.address[0] = self.copy(pointer.address[0]) + i += 1 if self.is_varsize(typeid): offset = self.varsize_offset_to_variable_part( typeid) length = (obj + self.varsize_offset_to_length(typeid)).signed[0] offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid) itemlength = self.varsize_item_sizes(typeid) - for i in range(length): + i = 0 + while i < length: item = obj + offset + itemlength * i - for j in range(len(offsets)): + j = 0 + while j < len(offsets): pointer = item + offsets[j] if pointer.address[0] != NULL: pointer.address[0] = self.copy(pointer.address[0]) + j += 1 + i += 1 def is_forwared(self, obj): return (obj - self.size_gc_header()).signed[1] < 0 @@ -289,12 +313,14 @@ def collect(self): roots = self.get_roots() + curr = roots.first while 1: - root = roots.pop() - if root == NULL: - break + root = curr.address[1] print "root", root, root.address[0] self.incref(root.address[0]) + if curr.address[0] == NULL: + break + curr = curr.address[0] while 1: candidate = self.zero_ref_counts.pop() self.length_zero_ref_counts -= 1 @@ -303,7 +329,6 @@ refcount = self.refcount(candidate) if refcount == 0: self.deallocate(candidate) - roots = self.get_roots() while 1: root = roots.pop() if root == NULL: @@ -321,20 +346,26 @@ typeid = gc_info.signed[1] print "deallocating", obj, typeid offsets = self.offsets_to_gc_pointers(typeid) - for i in range(len(offsets)): + i = 0 + while i < len(offsets): pointer = obj + offsets[i] self.decref(pointer.address[0]) + i += 1 if self.is_varsize(typeid): offset = self.varsize_offset_to_variable_part( typeid) length = (obj + self.varsize_offset_to_length(typeid)).signed[0] offsets = self.varsize_offsets_to_gcpointers_in_var_part(typeid) itemlength = self.varsize_item_sizes(typeid) - for i in range(length): + i = 0 + while i < length: item = obj + offset + itemlength * i - for j in range(len(offsets)): + j = 0 + while j < len(offsets): pointer = item + offsets[j] self.decref(pointer.address[0]) + j += 1 + i += 1 raw_free(addr) def incref(self, addr): From ericvrp at codespeak.net Wed Aug 31 00:08:55 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 31 Aug 2005 00:08:55 +0200 (CEST) Subject: [pypy-svn] r17107 - pypy/dist/pypy/translator/llvm Message-ID: <20050830220855.6C89927B73@code1.codespeak.net> Author: ericvrp Date: Wed Aug 31 00:08:54 2005 New Revision: 17107 Modified: pypy/dist/pypy/translator/llvm/genllvm.py Log: Prevent output of external functions where they are not used. This makes the output of the example in getting-started.txt somewhat better to read. Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Wed Aug 31 00:08:54 2005 @@ -230,12 +230,13 @@ self.translator.rtyper.specialize_more_blocks() self.db.setup_all() + using_external_functions = extfuncnode.ExternalFuncNode.used_external_functions.keys() != [] + if self.debug: self._print_node_stats() - if llcode_header is None: + if llcode_header is None and using_external_functions: self.generate_llfile(extern_decls) - lldeclarations, llimplementation = llcode_header, ll_functions #if self.debug: print 'gen_llvm_source typ_decl.writedatatypedecl) ' + time.ctime() #if self.debug: print 'gen_llvm_source n_nodes) %d' % len(self.db.getnodes()) @@ -256,9 +257,10 @@ comment = codewriter.comment nl = codewriter.newline - nl(); comment("EXTERNAL FUNCTION DECLARATIONS") ; nl() - for s in lldeclarations.split('\n'): - codewriter.append(s) + if using_external_functions: + nl(); comment("EXTERNAL FUNCTION DECLARATIONS") ; nl() + for s in llcode_header.split('\n'): + codewriter.append(s) nl(); comment("Type Declarations"); nl() @@ -382,9 +384,10 @@ codewriter.append(extfunc) depdone[dep] = True - nl(); comment("EXTERNAL FUNCTION IMPLEMENTATION") ; nl() - for s in llimplementation.split('\n'): - codewriter.append(s) + if using_external_functions: + nl(); comment("EXTERNAL FUNCTION IMPLEMENTATION") ; nl() + for s in ll_functions.split('\n'): + codewriter.append(s) comment("End of file") ; nl() if self.debug: print 'gen_llvm_source return) ' + time.ctime() From ericvrp at codespeak.net Wed Aug 31 00:11:08 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 31 Aug 2005 00:11:08 +0200 (CEST) Subject: [pypy-svn] r17108 - pypy/dist/pypy/translator/llvm Message-ID: <20050830221108.9880027B73@code1.codespeak.net> Author: ericvrp Date: Wed Aug 31 00:11:07 2005 New Revision: 17108 Modified: pypy/dist/pypy/translator/llvm/arraynode.py pypy/dist/pypy/translator/llvm/build_llvm_module.py pypy/dist/pypy/translator/llvm/extfuncnode.py Log: fixed bug where backslash was output in pbc's when this was also use as an escape character. Modified: pypy/dist/pypy/translator/llvm/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm/arraynode.py Wed Aug 31 00:11:07 2005 @@ -161,7 +161,7 @@ printables = dict([(ord(i), None) for i in ("0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + - "!#$%&()*+,-./:;<=>?@[\\]^_`{|}~ '")]) + "!#$%&()*+,-./:;<=>?@[]^_`{|}~ '")]) def get_arrayvalue(self): items = self.value.items Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py ============================================================================== --- pypy/dist/pypy/translator/llvm/build_llvm_module.py (original) +++ pypy/dist/pypy/translator/llvm/build_llvm_module.py Wed Aug 31 00:11:07 2005 @@ -91,15 +91,15 @@ cmds.append("llc %s %s.bc -f -o %s.s" % (EXCEPTIONS_SWITCHES, b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) if exe_name: - cmds.append("gcc %s.o %s -lm -ldl -o %s" % (b, gc_libs, exe_name)) + cmds.append("gcc %s.o %s -lm -ldl -pipe -o %s" % (b, gc_libs, exe_name)) object_files.append("%s.o" % b) else: #assume 64 bit platform (x86-64?) #this special case for x86-64 (called ia64 in llvm) can go as soon as llc supports ia64 assembly output! cmds.append("llc %s %s.bc -march=c -f -o %s.c" % (EXCEPTIONS_SWITCHES, b, b)) if exe_name: #XXX TODO: use CFLAGS when available - cmds.append("gcc %s.c -c -march=pentium4 -O2 -fomit-frame-pointer" % (b,)) - cmds.append("gcc %s.o %s -lm -ldl -o %s" % (b, gc_libs, exe_name)) + cmds.append("gcc %s.c -c -O3 -pipe" % (b,)) + cmds.append("gcc %s.o %s -lm -ldl -pipe -o %s" % (b, gc_libs, exe_name)) source_files.append("%s.c" % b) try: Modified: pypy/dist/pypy/translator/llvm/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/extfuncnode.py (original) +++ pypy/dist/pypy/translator/llvm/extfuncnode.py Wed Aug 31 00:11:07 2005 @@ -13,6 +13,7 @@ assert name.startswith("ll") name = "LL" + name[2:] self.ref = self.make_ref("%", name) + self.used_external_functions[self.ref] = True def getdecl(self): T = self.value._TYPE @@ -25,8 +26,8 @@ def writedecl(self, codewriter): codewriter.declare(self.getdecl()) - def writeimpl(self, codewriter): - self.used_external_functions[self.ref] = True + #def writeimpl(self, codewriter): + # self.used_external_functions[self.ref] = True def writeglobalconstants(self, codewriter): pass From cfbolz at codespeak.net Wed Aug 31 00:43:13 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 31 Aug 2005 00:43:13 +0200 (CEST) Subject: [pypy-svn] r17109 - in pypy/dist/pypy/rpython: . memory/test Message-ID: <20050830224313.554C827B73@code1.codespeak.net> Author: cfbolz Date: Wed Aug 31 00:43:08 2005 New Revision: 17109 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/test/test_address.py Log: some additions to the llinterpreter needed to interpret GCs: - replacement of prints with the correct usage of log - implementation of raw_memcopy + test - set the gc=None so that the create_gc thing can already use the llinterpreter for setup work - print_traceback had to be changed because the flowgraphs of the GC's functions are not in llinterpreter.flowgraphs Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Aug 31 00:43:08 2005 @@ -19,21 +19,23 @@ """ low level interpreter working with concrete values. """ def __init__(self, flowgraphs, typer, lltype=lltype): - if hasattr(lltype, "prepare_graphs_and_create_gc"): - self.gc = lltype.prepare_graphs_and_create_gc(self, flowgraphs) - else: - self.gc = None self.flowgraphs = flowgraphs self.bindings = {} self.typer = typer self.llt = lltype #module that contains the used lltype classes self.active_frame = None + # XXX hack hack hack: set gc to None because + # prepare_graphs_and_create_gc might already use the llinterpreter! + self.gc = None + if hasattr(lltype, "prepare_graphs_and_create_gc"): + self.gc = lltype.prepare_graphs_and_create_gc(self, flowgraphs) def getgraph(self, func): return self.flowgraphs[func] - def eval_function(self, func, args=()): - graph = self.getgraph(func) + def eval_function(self, func, args=(), graph=None): + if graph is None: + graph = self.getgraph(func) llframe = LLFrame(graph, args, self) try: return llframe.eval() @@ -51,7 +53,12 @@ frames.reverse() for frame in frames: print frame.graph.name, - print self.typer.annotator.annotated[frame.curr_block].__module__ + try: + print self.typer.annotator.annotated[frame.curr_block].__module__ + except KeyError: + # if the graph is from the GC it was not produced by the same + # translator :-( + print "" for i, operation in enumerate(frame.curr_block.operations): if i == frame.curr_operation_index: print "E ", @@ -60,11 +67,11 @@ print operation def find_roots(self): - print "find_roots" + log.find_roots("starting") frame = self.active_frame roots = [] while frame is not None: - print frame.graph.name + log.find_roots("graph", frame.graph.name) frame.find_roots(roots) frame = frame.f_back return roots @@ -228,7 +235,7 @@ self.make_llexception(e) def find_roots(self, roots): - print "find_roots in LLFrame", roots, self.curr_block.inputargs + log.find_roots(self.curr_block.inputargs) for arg in self.curr_block.inputargs: if (isinstance(arg, Variable) and isinstance(self.getval(arg), self.llt._ptr)): @@ -469,6 +476,11 @@ assert self.llt.typeOf(addr) == lladdress.Address lladdress.raw_free(addr) + def op_raw_memcopy(self, fromaddr, toaddr, size): + assert self.llt.typeOf(fromaddr) == lladdress.Address + assert self.llt.typeOf(toaddr) == lladdress.Address + lladdress.raw_memcopy(fromaddr, toaddr, size) + def op_raw_load(self, addr, typ, offset): assert isinstance(addr, lladdress.address) value = getattr(addr, str(typ).lower())[offset] Modified: pypy/dist/pypy/rpython/memory/test/test_address.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_address.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_address.py Wed Aug 31 00:43:08 2005 @@ -260,6 +260,20 @@ res = interpret(f, [0]) assert res + def test_raw_memcopy(self): + def f(): + addr = raw_malloc(100) + addr.signed[0] = 12 + (addr + 10).signed[0] = 42 + (addr + 20).char[0] = "a" + addr1 = raw_malloc(100) + raw_memcopy(addr, addr1, 100) + result = addr1.signed[0] == 12 + result = result and (addr1 + 10).signed[0] == 42 + result = result and (addr1 + 20).char[0] == "a" + return result + res = interpret(f, []) + assert res class TestAddressSimulation(object): def test_null_is_singleton(self): From cfbolz at codespeak.net Wed Aug 31 01:21:27 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 31 Aug 2005 01:21:27 +0200 (CEST) Subject: [pypy-svn] r17110 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050830232127.9E73127B73@code1.codespeak.net> Author: cfbolz Date: Wed Aug 31 01:21:18 2005 New Revision: 17110 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gclltype.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: let the GCs run on the llinterpreter as well (this makes the tests really slow, btw). Some trickery is required in the setup area, because a real GC instance is needed during setup time for the conversion of the constants in the graphs. This instance can not be reused on llinterp level, so we need to allocate one there. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Wed Aug 31 01:21:18 2005 @@ -10,12 +10,14 @@ class GCError(Exception): pass -def get_dummy_annotate(gc): +def get_dummy_annotate(gc_class): def dummy_annotate(): + gc = gc_class() gc.get_roots = dummy_get_roots1 #prevent the get_roots attribute to gc.get_roots = dummy_get_roots2 #be constants a = gc.malloc(1, 2) b = gc.malloc(2, 3) + gc.write_barrier(raw_malloc(1), raw_malloc(2), raw_malloc(1)) gc.collect() return a - b return dummy_annotate @@ -58,6 +60,11 @@ def write_barrier(self, addr, addr_to, addr_struct): addr_to.address[0] = addr + def free_memory(self): + #this will never be called at runtime, just during setup + "NOT_RPYTHON" + pass + class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" @@ -99,7 +106,8 @@ gc_info = curr.address[0] - self.size_gc_header() # constants roots are not malloced and thus don't have their mark # bit reset - gc_info.signed[0] = 0 + gc_info.signed[0] = 0 + free_non_gc_object(roots) while 1: #mark curr = objects.pop() ## print "object: ", curr @@ -131,6 +139,7 @@ j += 1 i += 1 gc_info.signed[0] = 1 + free_non_gc_object(objects) newmo = AddressLinkedList() curr_heap_size = 0 freed_size = 0 @@ -177,6 +186,13 @@ self.set_query_functions(None, None, None, None, None, None, None) self.get_roots = get_roots + def free_memory(self): + "NOT_RPYTHON" + raw_free(self.tospace) + self.tospace = NULL + raw_free(self.fromspace) + self.fromspace = NULL + def malloc(self, typeid, length=0): size = self.fixed_size(typeid) if self.is_varsize(typeid): @@ -185,7 +201,7 @@ if self.free + totalsize > self.top_of_space: self.collect() #XXX need to increase the space size if the object is too big - #for bonus points do big blocks differently + #for bonus points do big objects differently return self.malloc(typeid, length) result = self.free self.init_gc_object(result, typeid) @@ -193,7 +209,6 @@ self.free += totalsize return result + self.size_gc_header() - def collect(self): ## print "collecting" self.fromspace, self.tospace = self.tospace, self.fromspace @@ -206,6 +221,7 @@ break ## print "root", root, root.address[0] root.address[0] = self.copy(root.address[0]) + free_non_gc_object(roots) while scan < self.free: curr = scan + self.size_gc_header() self.trace_and_copy(curr) @@ -321,14 +337,23 @@ if curr.address[0] == NULL: break curr = curr.address[0] + dealloc_list = AddressLinkedList() while 1: candidate = self.zero_ref_counts.pop() self.length_zero_ref_counts -= 1 if candidate == NULL: break refcount = self.refcount(candidate) - if refcount == 0: - self.deallocate(candidate) + if (refcount == 0 and + (candidate - self.size_gc_header()).signed[1] != -1): + (candidate - self.size_gc_header()).signed[1] = -1 + dealloc_list.append(candidate) + while 1: + deallocate = dealloc_list.pop() + if deallocate == NULL: + break + self.deallocate(deallocate) + free_non_gc_object(dealloc_list) while 1: root = roots.pop() if root == NULL: Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Wed Aug 31 01:21:18 2005 @@ -36,9 +36,15 @@ from pypy.rpython.memory.gc import MarkSweepGC, SemiSpaceGC use_gc = MarkSweepGC -def create_mark_sweep_gc(llinterp, flowgraphs): - from pypy.rpython.memory.gcwrapper import GcWrapper +def create_gc(llinterp, flowgraphs): + from pypy.rpython.memory.gcwrapper import GcWrapper, AnnotatingGcWrapper wrapper = GcWrapper(llinterp, flowgraphs, use_gc) return wrapper + +def create_gc_run_on_llinterp(llinterp, flowgraphs): + from pypy.rpython.memory.gcwrapper import GcWrapper, AnnotatingGcWrapper + wrapper = AnnotatingGcWrapper(llinterp, flowgraphs, use_gc) + return wrapper + prepare_graphs_and_create_gc = create_no_gc Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Wed Aug 31 01:21:18 2005 @@ -124,6 +124,17 @@ self.varsize_offsets_to_gcpointers_in_var_part) +def getfunctionptr(translator, graphfunc): + """Make a functionptr from the given Python function.""" + graph = translator.getflowgraph(graphfunc) + llinputs = [v.concretetype for v in graph.getargs()] + lloutput = graph.getreturnvar().concretetype + FT = lltype.FuncType(llinputs, lloutput) + _callable = graphfunc + return lltypesimulation.functionptr(FT, graphfunc.func_name, + graph=graph, _callable=_callable) + + class GcWrapper(object): def __init__(self, llinterp, flowgraphs, gc_class): self.query_types = QueryTypes(llinterp) @@ -183,15 +194,15 @@ def update_changed_addresses(self): for i, root in enumerate(self.roots): - if root._address != self.pseudo_root_pointers.address[i]: - print "address changed:", root._address, self.pseudo_root_pointers.address[i] root.__dict__['_address'] = self.pseudo_root_pointers.address[i] - def get_roots(self): - print "getting roots" + def get_roots_from_llinterp(self): if self.pseudo_root_pointers != NULL: raw_free(self.pseudo_root_pointers) - self.roots = self.llinterp.find_roots() + self.constantroots + roots = [r for r in self.llinterp.find_roots() + if isinstance(r._TYPE.TO, + (lltype.GcStruct, lltype.GcArray))] + self.roots = roots + self.constantroots self.roots = [r for r in self.roots if isinstance(r._TYPE.TO, (lltype.Struct, lltype.Array))] @@ -199,6 +210,10 @@ self.pseudo_root_pointers = NULL else: self.pseudo_root_pointers = raw_malloc(len(self.roots) * INT_SIZE) + return self.roots + + def get_roots(self): + self.get_roots_from_llinterp() ll = AddressLinkedList() for i, root in enumerate(self.roots): self.pseudo_root_pointers.address[i] = root._address @@ -206,17 +221,79 @@ return ll class AnnotatingGcWrapper(GcWrapper): - def __init__(self, llinterp, gc, qt, constantroots): - super(AnnotatingGcWrapper, self).__init__(llinterp, gc, qt, - constantroots) + def __init__(self, llinterp, flowgraphs, gc_class): + super(AnnotatingGcWrapper, self).__init__(llinterp, flowgraphs, gc_class) + # tell the real-built gc to free its memory as it is only used for + # initialisation + self.gc.free_memory() self.annotate_rtype_gc() def annotate_rtype_gc(self): - #XXXXX unfinished - func = gc.get_dummy_annotate(self.gc) - self.gc.get_roots = gc.dummy_get_roots + # annotate and specialize functions + gc_class = self.gc.__class__ + def instantiate_linked_list(): + return AddressLinkedList() + f1, f2, f3, f4, f5, f6, f7 = self.query_types.create_query_functions() + def instantiate_gc(): + gc = gc_class() + gc.set_query_functions(f1, f2, f3, f4, f5, f6, f7) + return gc + func = gc.get_dummy_annotate(self.gc.__class__) + self.gc.get_roots = gc.dummy_get_roots1 a = RPythonAnnotator() - res = a.build_types(func, []) - a.translator.view() + a.build_types(instantiate_gc, []) + a.build_types(func, []) + a.build_types(instantiate_linked_list, []) a.translator.specialize() - self.gc.get_roots = self.get_roots + self.annotator = a + + # convert constants + fgcc = FlowGraphConstantConverter(a.translator.flowgraphs) + fgcc.convert() + self.malloc_graph = a.translator.flowgraphs[self.gc.malloc.im_func] + + # create a gc via invoking instantiate_gc + self.gcptr = self.llinterp.eval_function( + instantiate_gc, graph=a.translator.flowgraphs[instantiate_gc]) + GETROOTS_FUNCTYPE = lltype.typeOf( + getfunctionptr(a.translator, gc.dummy_get_roots1)).TO + setattr(self.gcptr, "inst_get_roots", + lltypesimulation.functionptr(GETROOTS_FUNCTYPE, "get_roots", + _callable=self.get_roots)) + + #get funcptrs neccessary to build the result of get_roots + self.instantiate_linked_list = getfunctionptr( + a.translator, instantiate_linked_list) + self.append_linked_list = getfunctionptr( + a.translator, AddressLinkedList.append.im_func) + self.pop_linked_list = getfunctionptr( + a.translator, AddressLinkedList.pop.im_func) + self.gc.get_roots = None + self.translator = a.translator +# a.translator.view() + + def get_arg_malloc(self, TYPE, size=0): + typeid = self.query_types.get_typeid(TYPE) + return [self.gcptr, typeid, size] + + def get_funcptr_malloc(self): + return self.llinterp.llt.functionptr(gc.gc_interface["malloc"], "malloc", + _callable=self.gc.malloc, + graph=self.malloc_graph) + + def adjust_result_malloc(self, address, TYPE, size=0): + result = lltypesimulation.init_object_on_address(address, TYPE, size) + self.update_changed_addresses() + return result + + def get_roots(self): + # call the llinterpreter to construct the result in a suitable way + self.get_roots_from_llinterp() + ll = self.llinterp.active_frame.op_direct_call( + self.instantiate_linked_list) + for i, root in enumerate(self.roots): + self.pseudo_root_pointers.address[i] = root._address + self.llinterp.active_frame.op_direct_call( + self.append_linked_list, ll, + self.pseudo_root_pointers + INT_SIZE * i) + return ll Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Wed Aug 31 01:21:18 2005 @@ -1,4 +1,5 @@ import py +import sys from pypy.annotation import model as annmodel from pypy.translator.annrpython import RPythonAnnotator @@ -14,87 +15,21 @@ from pypy.rpython.objectmodel import free_non_gc_object def setup_module(mod): + def stdout_ignore_ll_functions(msg): + strmsg = str(msg) + if "evaluating" in strmsg and "ll_" in strmsg: + return + print >>sys.stdout, strmsg mod.logstate = py.log._getstate() py.log.setconsumer("llinterp", py.log.STDOUT) + py.log.setconsumer("llinterp frame", stdout_ignore_ll_functions) py.log.setconsumer("llinterp operation", None) - gclltype.prepare_graphs_and_create_gc = gclltype.create_mark_sweep_gc + gclltype.prepare_graphs_and_create_gc = gclltype.create_gc def teardown_module(mod): gclltype.prepare_graphs_and_create_gc = gclltype.create_no_gc -class PseudoObjectModel(object): - """Object model for testing purposes: you can specify roots and a - layout_mapping which is a dictionary of typeids to a list of offsets of - pointers in an object""" - def __init__(self, roots, layout_mapping, size_mapping): - self.roots = roots - self.layout_mapping = layout_mapping - self.size_mapping = size_mapping - - def get_roots(self): - self.roots - ll = AddressLinkedList() - for root in self.roots: - ll.append(root) - return ll - - def is_varsize(self, typeid): - False - - def fixed_size(self, typeid): - return self.size_mapping[typeid] - - def offsets_to_gc_pointers(self, typeid): - return self.layout_mapping[typeid] - class TestMarkSweepGC(object): - def DONOTtest_simple(self): - variables = raw_malloc(4 * INT_SIZE) - roots = [variables + i * INT_SIZE for i in range(4)] - layout0 = [] #int - layout1 = [0, INT_SIZE] #(ptr, ptr) - om = PseudoObjectModel(roots, {0: layout0, 1: layout1}, {0: INT_SIZE, 1: 2 * INT_SIZE}) - gc = MarkSweepGC(om, 2 ** 16) - variables.address[0] = gc.malloc(0) - variables.address[1] = gc.malloc(0) - variables.address[2] = gc.malloc(0) - variables.address[3] = gc.malloc(0) - variables.address[0].signed[0] = 0 - variables.address[1].signed[0] = 1 - variables.address[2].signed[0] = 2 - variables.address[3].signed[0] = 3 - print "roots", roots - gc.collect() #does not crash - assert variables.address[0].signed[0] == 0 - assert variables.address[1].signed[0] == 1 - assert variables.address[2].signed[0] == 2 - assert variables.address[3].signed[0] == 3 - addr = gc.malloc(0) - addr.signed[0] = 1 - print "roots", roots - gc.collect() - py.test.raises(MemorySimulatorError, "addr.signed[0]") - variables.address[0] = gc.malloc(1) - variables.address[0].address[0] = variables.address[1] - variables.address[0].address[1] = NULL - print "roots", roots - gc.collect() #does not crash - assert variables.address[0].address[0] == variables.address[1] - assert variables.address[0].address[1] == NULL - addr0 = gc.malloc(1) - addr0.address[1] = NULL - addr1 = gc.malloc(1) - addr1.address[0] = addr1.address[1] = NULL - addr0.address[0] = addr1 - addr2 = variables.address[1] - print "addr0, addr1, addr2 =", addr0, addr1, addr2 - variables.address[1] == NULL - variables.address[0].address[0] = NULL - print "roots", roots - gc.collect() - py.test.raises(MemorySimulatorError, "addr0.signed[0]") - py.test.raises(MemorySimulatorError, "addr1.signed[0]") - def test_llinterp_lists(self): curr = simulator.current_size def malloc_a_lot(): @@ -129,7 +64,7 @@ def test_global_list(self): lst = [] def append_to_list(i, j): - lst.append([i] * 500) + lst.append([i] * 50) return lst[j][0] res = interpret(append_to_list, [0, 0]) assert res == 0 @@ -148,157 +83,36 @@ assert res == concat(100) assert simulator.current_size - curr < 16000 +class TestMarkSweepGCRunningOnLLinterp(TestMarkSweepGC): + def setup_class(cls): + cls.prep_old = gclltype.prepare_graphs_and_create_gc + gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp + def teardown_class(cls): + gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func -class TestSemiSpaceGC(object): +class TestSemiSpaceGC(TestMarkSweepGC): def setup_class(cls): gclltype.use_gc = SemiSpaceGC cls.old = gclltype.use_gc def teardown_class(cls): gclltype.use_gc = cls.old - def DONOTtest_simple(self): - variables = raw_malloc(4 * INT_SIZE) - roots = [variables + i * INT_SIZE for i in range(4)] - layout0 = [] #int - layout1 = [0, INT_SIZE] #(ptr, ptr) - om = PseudoObjectModel(roots, {0: layout0, 1: layout1}, {0: INT_SIZE, 1: 2 * INT_SIZE}) - gc = SemiSpaceGC(om, 2 ** 16) - variables.address[0] = gc.malloc(0) - variables.address[1] = gc.malloc(0) - variables.address[2] = gc.malloc(0) - variables.address[3] = gc.malloc(0) - variables.address[0].signed[0] = 0 - variables.address[1].signed[0] = 1 - variables.address[2].signed[0] = 2 - variables.address[3].signed[0] = 3 - print "roots", roots - gc.collect() #does not crash - assert variables.address[0].signed[0] == 0 - assert variables.address[1].signed[0] == 1 - assert variables.address[2].signed[0] == 2 - assert variables.address[3].signed[0] == 3 - addr = gc.malloc(0) - addr.signed[0] = 1 - print "roots", roots - gc.collect() -## py.test.raises(MemorySimulatorError, "addr.signed[0]") - variables.address[0] = gc.malloc(1) - variables.address[0].address[0] = variables.address[1] - variables.address[0].address[1] = NULL - print "roots", roots - gc.collect() #does not crash - assert variables.address[0].address[0] == variables.address[1] - assert variables.address[0].address[1] == NULL - addr0 = gc.malloc(1) - addr0.address[1] = NULL - addr1 = gc.malloc(1) - addr1.address[0] = addr1.address[1] = NULL - addr0.address[0] = addr1 - addr2 = variables.address[1] - print "addr0, addr1, addr2 =", addr0, addr1, addr2 - variables.address[1] == NULL - variables.address[0].address[0] = NULL - print "roots", roots - gc.collect() - - def test_llinterp_lists(self): - curr = simulator.current_size - def malloc_a_lot(): - i = 0 - while i < 10: - i += 1 - a = [1] * 10 - j = 0 - while j < 20: - j += 1 - a.append(j) - res = interpret(malloc_a_lot, []) - assert simulator.current_size - curr < 16000 - print "size before: %s, size after %s" % (curr, simulator.current_size) - - def test_llinterp_tuples(self): - curr = simulator.current_size - def malloc_a_lot(): - i = 0 - while i < 10: - i += 1 - a = (1, 2, i) - b = [a] * 10 - j = 0 - while j < 20: - j += 1 - b.append((1, j, i)) - res = interpret(malloc_a_lot, []) - assert simulator.current_size - curr < 16000 - print "size before: %s, size after %s" % (curr, simulator.current_size) +class TestSemiSpaceGCRunningOnLLinterp(TestMarkSweepGC): + def setup_class(cls): + cls.prep_old = gclltype.prepare_graphs_and_create_gc + gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp + gclltype.use_gc = SemiSpaceGC + cls.old = gclltype.use_gc - def test_global_list(self): - lst = [] - def append_to_list(i, j): - lst.append([i] * 50) - return lst[j][0] - res = interpret(append_to_list, [0, 0]) - assert res == 0 - for i in range(1, 15): - res = interpret(append_to_list, [i, i - 1]) - assert res == i - 1 # crashes if constants are not considered roots + def teardown_class(cls): + gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func + gclltype.use_gc = cls.old - def test_string_concatenation(self): - curr = simulator.current_size - def concat(j): - lst = [] - for i in range(j): - lst.append(str(i)) - return len("".join(lst)) - res = interpret(concat, [100]) - assert res == concat(100) - assert simulator.current_size - curr < 16000 -class DONOTTestDeferredRefcountingGC(object): +class DONOTTestDeferredRefcountingGC(TestMarkSweepGC): def setup_class(cls): gclltype.use_gc = DeferredRefcountingGC cls.old = gclltype.use_gc def teardown_class(cls): gclltype.use_gc = cls.old - def test_llinterp_lists(self): - curr = simulator.current_size - def malloc_a_lot(): - i = 0 - while i < 10: - i += 1 - a = [1] * 10 - j = 0 - while j < 20: - j += 1 - a.append(j) - res = interpret(malloc_a_lot, []) - assert simulator.current_size - curr < 16000 - print "size before: %s, size after %s" % (curr, simulator.current_size) - - def test_llinterp_tuples(self): - curr = simulator.current_size - def malloc_a_lot(): - i = 0 - while i < 10: - i += 1 - a = (1, 2, i) - b = [a] * 10 - j = 0 - while j < 20: - j += 1 - b.append((1, j, i)) - res = interpret(malloc_a_lot, []) - assert simulator.current_size - curr < 16000 - print "size before: %s, size after %s" % (curr, simulator.current_size) - - def test_global_list(self): - lst = [] - def append_to_list(i, j): - lst.append([i] * 500) - return lst[j][0] - res = interpret(append_to_list, [0, 0]) - assert res == 0 - for i in range(1, 15): - res = interpret(append_to_list, [i, i - 1]) - assert res == i - 1 # crashes if constants are not considered roots From cfbolz at codespeak.net Wed Aug 31 03:59:55 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 31 Aug 2005 03:59:55 +0200 (CEST) Subject: [pypy-svn] r17111 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20050831015955.E6E7D27B73@code1.codespeak.net> Author: cfbolz Date: Wed Aug 31 03:59:46 2005 New Revision: 17111 Modified: pypy/dist/pypy/rpython/memory/convertlltype.py pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/gcwrapper.py pypy/dist/pypy/rpython/memory/test/test_gc.py Log: fix the deferred refcounting GC and make in running on the llinterpreter + tests Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Wed Aug 31 03:59:46 2005 @@ -58,7 +58,7 @@ self.curraddress += size if self.gc is not None: typeid = self.query_types.get_typeid(TYPE) - self.gc.init_gc_object(startaddr, typeid) + self.gc.init_gc_object_immortal(startaddr, typeid) startaddr += self.gc.size_gc_header(typeid) self.curraddress += self.gc.size_gc_header(typeid) ptr = init_object_on_address(startaddr, TYPE, arraylength) @@ -98,7 +98,7 @@ self.curraddress += size if self.gc is not None: typeid = self.query_types.get_typeid(TYPE) - self.gc.init_gc_object(startaddr, typeid) + self.gc.init_gc_object_immortal(startaddr, typeid) startaddr += self.gc.size_gc_header(typeid) self.curraddress += self.gc.size_gc_header(typeid) ptr = init_object_on_address(startaddr, TYPE, inlinedarraylength) Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Wed Aug 31 03:59:46 2005 @@ -5,6 +5,8 @@ from pypy.rpython import lltype from pypy.rpython.objectmodel import free_non_gc_object +import sys + int_size = lltypesimulation.sizeof(lltype.Signed) class GCError(Exception): @@ -171,7 +173,7 @@ def init_gc_object(self, addr, typeid): addr.signed[0] = 0 addr.signed[1] = typeid - + init_gc_object_immortal = init_gc_object class SemiSpaceGC(GCBase): _alloc_flavor_ = "raw" @@ -305,17 +307,18 @@ def init_gc_object(self, addr, typeid): addr.signed[0] = 0 addr.signed[1] = typeid - + init_gc_object_immortal = init_gc_object class DeferredRefcountingGC(GCBase): _alloc_flavor_ = "raw" - def __init__(self, max_refcount_zero=10, get_roots=None): + def __init__(self, max_refcount_zero=50, get_roots=None): self.zero_ref_counts = AddressLinkedList() self.length_zero_ref_counts = 0 self.max_refcount_zero = max_refcount_zero self.set_query_functions(None, None, None, None, None, None, None) self.get_roots = get_roots + self.collecting = False def malloc(self, typeid, length=0): size = self.fixed_size(typeid) @@ -323,53 +326,61 @@ size += length * self.varsize_item_sizes(typeid) size_gc_header = self.size_gc_header() result = raw_malloc(size + size_gc_header) - print "mallocing %s, size %s at %s" % (typeid, size, result) - self.init_gc_object(result, typeid) +## print "mallocing %s, size %s at %s" % (typeid, size, result) + result.signed[0] = 0 # refcount + result.signed[1] = typeid return result + size_gc_header def collect(self): + if self.collecting: + return + else: + self.collecting = True roots = self.get_roots() curr = roots.first while 1: root = curr.address[1] - print "root", root, root.address[0] +## print "root", root, root.address[0] +## assert self.refcount(root.address[0]) >= 0, "refcount negative" self.incref(root.address[0]) if curr.address[0] == NULL: break curr = curr.address[0] dealloc_list = AddressLinkedList() + self.length_zero_ref_counts = 0 while 1: candidate = self.zero_ref_counts.pop() - self.length_zero_ref_counts -= 1 if candidate == NULL: break refcount = self.refcount(candidate) - if (refcount == 0 and - (candidate - self.size_gc_header()).signed[1] != -1): - (candidate - self.size_gc_header()).signed[1] = -1 + typeid = (candidate - self.size_gc_header()).signed[1] + if (refcount == 0 and typeid >= 0): + (candidate - self.size_gc_header()).signed[1] = -typeid - 1 dealloc_list.append(candidate) while 1: deallocate = dealloc_list.pop() if deallocate == NULL: break + typeid = (deallocate - self.size_gc_header()).signed[1] + (deallocate - self.size_gc_header()).signed[1] = -typeid - 1 self.deallocate(deallocate) free_non_gc_object(dealloc_list) while 1: root = roots.pop() if root == NULL: break - print "root", root, root.address[0] self.decref(root.address[0]) + self.collecting = False def write_barrier(self, addr, addr_to, addr_struct): self.decref(addr_to.address[0]) addr_to.address[0] = addr self.incref(addr) - def deallocate(self, addr): + def deallocate(self, obj): gc_info = obj - self.size_gc_header() typeid = gc_info.signed[1] - print "deallocating", obj, typeid +## print "deallocating", obj, typeid offsets = self.offsets_to_gc_pointers(typeid) i = 0 while i < len(offsets): @@ -391,7 +402,7 @@ self.decref(pointer.address[0]) j += 1 i += 1 - raw_free(addr) + raw_free(gc_info) def incref(self, addr): (addr - self.size_gc_header()).signed[0] += 1 @@ -400,21 +411,25 @@ if addr == NULL: return refcount = (addr - self.size_gc_header()).signed[0] +## assert refcount > 0, "neg refcount" if refcount == 1: self.zero_ref_counts.append(addr) self.length_zero_ref_counts += 1 if self.length_zero_ref_counts > self.max_refcount_zero: self.collect() (addr - self.size_gc_header()).signed[0] = refcount - 1 - assert refcount > 0 def refcount(self, addr): - (addr - self.size_gc_header()).signed[0] + return (addr - self.size_gc_header()).signed[0] def init_gc_object(self, addr, typeid): addr.signed[0] = 0 # refcount addr.signed[1] = typeid + def init_gc_object_immortal(self, addr, typeid): + addr.signed[0] = sys.maxint // 2 # refcount + addr.signed[1] = typeid + def size_gc_header(self, typeid=0): return int_size * 2 Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Wed Aug 31 03:59:46 2005 @@ -190,7 +190,7 @@ return self.llinterp.llt.functionptr(gc.gc_interface["write_barrier"], "write_barrier", _callable=self.gc.write_barrier) - + def update_changed_addresses(self): for i, root in enumerate(self.roots): @@ -251,6 +251,8 @@ fgcc = FlowGraphConstantConverter(a.translator.flowgraphs) fgcc.convert() self.malloc_graph = a.translator.flowgraphs[self.gc.malloc.im_func] + self.write_barrier_graph = a.translator.flowgraphs[ + self.gc.write_barrier.im_func] # create a gc via invoking instantiate_gc self.gcptr = self.llinterp.eval_function( @@ -260,7 +262,6 @@ setattr(self.gcptr, "inst_get_roots", lltypesimulation.functionptr(GETROOTS_FUNCTYPE, "get_roots", _callable=self.get_roots)) - #get funcptrs neccessary to build the result of get_roots self.instantiate_linked_list = getfunctionptr( a.translator, instantiate_linked_list) @@ -270,7 +271,7 @@ a.translator, AddressLinkedList.pop.im_func) self.gc.get_roots = None self.translator = a.translator -# a.translator.view() +## a.translator.view() def get_arg_malloc(self, TYPE, size=0): typeid = self.query_types.get_typeid(TYPE) @@ -286,6 +287,26 @@ self.update_changed_addresses() return result + def get_arg_write_barrier(self, obj, index_or_field, item): + #XXX: quick hack to get the correct addresses, fix later + layout = lltypelayout.get_layout(lltype.typeOf(obj).TO) + if isinstance(lltype.typeOf(obj).TO, lltype.Array): + assert isinstance(index_or_field, int) + offset = layout[0] + layout[1] * index_or_field + addr_to = obj._address + layout[0] + index_or_field * layout[1] + return self.gcptr, item._address, addr_to, obj._address + else: + offset = layout[index_or_field] + addr_to = obj._address + offset + return self.gcptr, item._address, addr_to, obj._address + + def get_funcptr_write_barrier(self): + return self.llinterp.llt.functionptr(gc.gc_interface["write_barrier"], + "write_barrier", + _callable=self.gc.write_barrier, + graph=self.write_barrier_graph) + + def get_roots(self): # call the llinterpreter to construct the result in a suitable way self.get_roots_from_llinterp() Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Wed Aug 31 03:59:46 2005 @@ -30,6 +30,15 @@ gclltype.prepare_graphs_and_create_gc = gclltype.create_no_gc class TestMarkSweepGC(object): + def setup_class(cls): + cls.prep_old = gclltype.prepare_graphs_and_create_gc + gclltype.use_gc = MarkSweepGC + cls.old = gclltype.use_gc + + def teardown_class(cls): + gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func + gclltype.use_gc = cls.old + def test_llinterp_lists(self): curr = simulator.current_size def malloc_a_lot(): @@ -108,11 +117,21 @@ gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func gclltype.use_gc = cls.old - -class DONOTTestDeferredRefcountingGC(TestMarkSweepGC): +class TestDeferredRefcountingGC(TestMarkSweepGC): def setup_class(cls): gclltype.use_gc = DeferredRefcountingGC cls.old = gclltype.use_gc def teardown_class(cls): gclltype.use_gc = cls.old + +class TestDeferredRefcountingGCRunningOnLLinterp(TestMarkSweepGC): + def setup_class(cls): + cls.prep_old = gclltype.prepare_graphs_and_create_gc + gclltype.prepare_graphs_and_create_gc = gclltype.create_gc_run_on_llinterp + gclltype.use_gc = DeferredRefcountingGC + cls.old = gclltype.use_gc + + def teardown_class(cls): + gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func + gclltype.use_gc = cls.old From hpk at codespeak.net Wed Aug 31 09:45:35 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 31 Aug 2005 09:45:35 +0200 (CEST) Subject: [pypy-svn] r17112 - pypy/extradoc/sprintinfo Message-ID: <20050831074535.DA74A27B76@code1.codespeak.net> Author: hpk Date: Wed Aug 31 09:45:34 2005 New Revision: 17112 Added: pypy/extradoc/sprintinfo/Heidelberg-report.txt Log: a first draft of the heidelberg sprint report. please check/extend/review. i fear it's not complete, i only skimmed the commit messages and didn't list or know about all of the small steps. Added: pypy/extradoc/sprintinfo/Heidelberg-report.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/Heidelberg-report.txt Wed Aug 31 09:45:34 2005 @@ -0,0 +1,121 @@ + +Heidelberg sprint report 22nd-29th August +============================================= + +The heidelberg sprint was announced_ late July +and around `13 people registered`_ and showed up +at the nice Heidelberg physics institute which +Carl Friedrich Bolz had organized for us. + +The sprint was focused on getting a `0.7.0 release out`_ +and improve and refine crucial areas like +threading, GC and CPython compliancy. Here +is what people worked on in a somewhat chronological +particular order: + +- Samuele and Carl worked on refactoring the parts of genc + that are responsible for the use of refcounting in the translation to make + it possible to compile with a different GC strategy. It turned out that + refcounting is kind of deeply embedded into genc so it took a lot + of time to introduce sensible hooks that other GCs could use. + +- Armin and Richard changed genc so that it can handle + locks as external objects that Armin had to introduce to + implement threading in PyPy. For now we have a simple GIL but it is not + deeply implanted in the interpreter so we should be able to + change that later. After two days of hacking they were finished + although some more translation related issues popped up and + were fixed. + +- Holger continously prepared the release infrastructure and refactored + the website and documentation to allow it to be presented + by version in the future. For the next time, we will nevertheless + continue to use only "dist" as we don't expect interesting + or neccessaries branches/splits of documentation or website + content. + +- Anders L. and Jacob worked on compliancy worked on compliancy: + they fixed some failing tests related to unicode and codecs + and binascii. + +- Initially Ludovic and Nik worked on making more parts of our + compiler RPython and Ludovic continued this effort on "astcompiler" + for some days before he focused on fixing compiler compliancy + bugs along with Holger and Samuele and a host of others + who had fun with CPython's somewhat non-compliant compiler + package. + +- Laura continued working on a docstring exctraction tool + and cared for getting docstrings into PyPy builtin + type objects. + +- Niklaus Heidimann moved his _sre implementation + *incrementally* to interpreter level and succeeded + to have it fully running and translateable for the + release! + +- Richard Emslie and Eric van Riet Paap continously worked + on improving and fixing LLVM. They succeeded in reusing + genc's external function implementations but had to setup + a build indirection via codespeak: to compile llvm-files + source code is sent to a CGI on codespeak and the result + is sent back to the client. This makes it easier for + people who don't have a CVS version of LLVM installed. + They discovered and communicated with llvm-dev about + LLVM bugs. In the end they managed they managed to + have a full LLVM backend documented and running for + the 0.7.0 release! + +- Christian worked on implementing various external functions + and hacked a "fakecompiler" compilation with the translated + pypy-c that delegates bytecode compilation to a python + process. The idea was to have running of tests on the + translated PyPy work. Christian also worked on fixing + the build process for win32. + +- Many of us worked on the break day (which just was too rainy) + and increased test compliancy by 10%, fixing and tackling + numerous issues. Anders C. was one of the person who + continously worked on classifying and fixing core tests. + holger with help from Niklaus fixed a couple of conftest + compliancy-testing related bugs. + +- Ludovic and Holger refactored the compiler and parser option + handling and added a README.compiling to make things slightly + less obscure. + +- Armin, Samuele and others refactored the translation entry + points and also made the pypy-c/pypy-llvm entry points nicer + (adding --info and --version options). Samuele also unified + the way we specify which app/mixed modules should be used. + +- Carl Friedrich and Holger updated a lot of documentation and + release issues, worked on getting-started, wrote the release + announcement, the LICENSE files and checked that examples still + work and make sense. + +- Carl also quickly implemented the 'errno' mixed module. + +- Bea worked on coordination and management issues + and wrote a document describing our sprint development + process. She also worked on a "dissemination plan" + and talked to various interested parties regarding + their plans for the future. She also convened with + Jacob and Stephan on monday to talk about management + responsibilities in the near future. There now is the + "3rd amendment" to the EU contract scheduled for + 7th September. Holger and Bea listed the steps + required for getting Michael Hudson on the project + through the University of Bristol. + +On sunday afternoon (basically the last day where mostly +everbody was there) we had a kind of sprint-conclusion +and what to do next meeting, originally planned as +the technical board meeting. There we talked about +the next areas for cleanup (partly listed in this +`pypy-dev mail`_). + +.. _`13 people registered`: http://codespeak.net/pypy/extradoc/sprintinfo/heidelberg-people.html +.. _`announced`: http://codespeak.net/pypy/extradoc/sprintinfo/Heidelberg-sprint.html +.. _`0.7.0 release out`: http://codespeak.net/pipermail/pypy-dev/2005q3/002294.html +.. _`pypy-dev mail`: http://codespeak.net/pipermail/pypy-dev/2005q3/002301.html From ale at codespeak.net Wed Aug 31 11:20:51 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Wed, 31 Aug 2005 11:20:51 +0200 (CEST) Subject: [pypy-svn] r17114 - pypy/dist/pypy/module/_codecs Message-ID: <20050831092051.154C727B80@code1.codespeak.net> Author: ale Date: Wed Aug 31 11:20:51 2005 New Revision: 17114 Modified: pypy/dist/pypy/module/_codecs/app_codecs.py Log: bug fixes for partial evaluation of utf-16 and utf-8 bug fixes for named unicode characters Modified: pypy/dist/pypy/module/_codecs/app_codecs.py ============================================================================== --- pypy/dist/pypy/module/_codecs/app_codecs.py (original) +++ pypy/dist/pypy/module/_codecs/app_codecs.py Wed Aug 31 11:20:51 2005 @@ -66,17 +66,17 @@ a tuple of functions. """ - result = codec_search_cache.get(encoding,None) + result = codec_search_cache.get(encoding, None) if not result: if codec_need_encodings: import encodings if len(codec_search_path) == 0: raise LookupError("no codec search functions registered: can't find encoding") del codec_need_encodings[:] - if not isinstance(encoding,str): + if not isinstance(encoding, str): raise TypeError("Encoding must be a string") for search in codec_search_path: - result=search(encoding) + result = search(encoding) if result : if not( type(result) == tuple and len(result) == 4): raise TypeError("codec search functions must return 4-tuples") @@ -102,17 +102,17 @@ """ if encoding == None: encoding = sys.getdefaultencoding() - if isinstance(encoding,str): + if isinstance(encoding, str): encoder = lookup(encoding)[0] - if encoder and isinstance(errors,str): - res = encoder(v,errors) + if encoder and isinstance(errors, str): + res = encoder(v, errors) return res[0] else: raise TypeError("Errors must be a string") else: raise TypeError("Encoding must be a string") -def decode(obj,encoding=None,errors='strict'): +def decode(obj, encoding=None, errors='strict'): """decode(obj, [encoding[,errors]]) -> object Decodes obj using the codec registered for encoding. encoding defaults @@ -161,13 +161,13 @@ v = s[1:-1] return v,len(v) -def utf_8_decode( data,errors='strict',final=0): +def utf_8_decode( data,errors='strict',final=False): """None """ consumed = len(data) if final: - consumed = 0 - res,consumed = PyUnicode_DecodeUTF8Stateful(data, len(data), errors, consumed) + consumed = 0 + res,consumed = PyUnicode_DecodeUTF8Stateful(data, len(data), errors, final) res = u''.join(res) return res, consumed @@ -199,13 +199,13 @@ res = u''.join(res) return res, len(res) -def utf_16_decode( data,errors='strict',final=None): +def utf_16_decode( data,errors='strict',final=False): """None """ consumed = len(data) if final: - consumed = 0 - res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'native',consumed) + consumed = 0 + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,'native',final) res = ''.join(res) return res, consumed @@ -284,19 +284,19 @@ res = u''.join(p) return res, len(res) -def utf_16_ex_decode( data,errors='strict',byteorder=0,final = 0): +def utf_16_ex_decode( data, errors='strict', byteorder=0, final=0): """None """ if byteorder == 0: - bm = 'native' + bm = 'native' elif byteorder == -1: - bm = 'little' + bm = 'little' else: - bm = 'big' + bm = 'big' consumed = len(data) if final: - consumed = 0 - res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data,len(data),errors,bm,consumed) + consumed = 0 + res,consumed,byteorder = PyUnicode_DecodeUTF16Stateful(data, len(data), errors, bm, consumed) res = ''.join(res) return res, consumed, byteorder @@ -885,9 +885,10 @@ len(unicode), None) -def PyUnicode_DecodeUTF16Stateful(s,size,errors,byteorder='native',consumed=None): +def PyUnicode_DecodeUTF16Stateful(s,size,errors,byteorder='native',final=True): bo = 0 #/* assume native ordering by default */ + consumed = 0 errmsg = "" if sys.byteorder == 'little': @@ -946,7 +947,7 @@ #/* remaining bytes at the end? (size should be even) */ if (len(s)-q<2): - if (consumed): + if not final: break errmsg = "truncated data" startinpos = q @@ -1083,7 +1084,7 @@ def PyUnicode_DecodeUTF8(s, size, errors): - return PyUnicode_DecodeUTF8Stateful(s, size, errors, None) + return PyUnicode_DecodeUTF8Stateful(s, size, errors, False) ## /* Map UTF-8 encoded prefix byte to sequence length. zero means ## illegal prefix. see RFC 2279 for details */ @@ -1106,13 +1107,13 @@ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0 ] -def PyUnicode_DecodeUTF8Stateful(s,size,errors,consumed): +def PyUnicode_DecodeUTF8Stateful(s,size,errors,final): + consumed = 0 if (size == 0): - if (consumed): + if not final: consumed = 0 return u'', consumed - p = [] pos = 0 while pos < size: @@ -1125,7 +1126,7 @@ n = utf8_code_length[ord(ch)] startinpos = pos if (startinpos + n > size): - if (consumed): + if not final: break else: errmsg = "unexpected end of data" @@ -1265,7 +1266,7 @@ #continue - if (consumed): + if not final: consumed = pos return p, pos # consumed @@ -1429,18 +1430,18 @@ pos += 1 ## /* \x escapes */ #if ch == '\n': break; - if ch == '\\': p += '\\' - elif ch == '\'': p += '\'' - elif ch == '\"': p += '\"' - elif ch == 'b': p += '\b' - elif ch == 'f': p += '\014' #/* FF */ - elif ch == 't': p += '\t' - elif ch == 'n': p += '\n' + if ch == '\\': p += u'\\' + elif ch == '\'': p += u'\'' + elif ch == '\"': p += u'\"' + elif ch == 'b': p += u'\b' + elif ch == 'f': p += u'\014' #/* FF */ + elif ch == 't': p += u'\t' + elif ch == 'n': p += u'\n' elif ch == 'r': - p += '\r' + p += u'\r' - elif ch == 'v': p += '\013' #break; /* VT */ - elif ch == 'a': p += '\007' # break; /* BEL, not classic C */ + elif ch == 'v': p += u'\013' #break; /* VT */ + elif ch == 'a': p += u'\007' # break; /* BEL, not classic C */ ## /* \OOO (octal) escapes */ elif ch in [ '0','1', '2', '3','4', '5', '6','7']: @@ -1488,27 +1489,26 @@ except ImportError: message = "\\N escapes not supported (can't load unicodedata module)" unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,size) - if (s[look] == '{'): + if look < size and s[look] == '{': #/* look for the closing brace */ while (look < size and s[look] != '}'): look += 1 if (look > pos+1 and look < size and s[look] == '}'): #/* found a name. look it up in the unicode database */ message = "unknown Unicode character name" - look += 1 + st = s[pos+1:look] try: - chr = unicodedata.lookup(s[pos:look]) - #x = hexescape(chr,pos+1,8,message,errors) - except KeyError: - x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look) + chr = unicodedata.lookup("%s" % st) + except KeyError, e: + x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look+1) else: - x = hexescape(s,pos+1,look-pos,message,errors) + x = chr,look + 1 p += x[0] pos = x[1] else: - x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look) + x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look+1) else: - x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look) + x=unicode_call_errorhandler(errors,"unicodeescape",message,s,pos-1,look+1) else: if (pos > size): message = "\\ at end of string" From pedronis at codespeak.net Wed Aug 31 14:43:00 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 31 Aug 2005 14:43:00 +0200 (CEST) Subject: [pypy-svn] r17116 - pypy/dist/pypy/translator/goal Message-ID: <20050831124300.7970527B56@code1.codespeak.net> Author: pedronis Date: Wed Aug 31 14:42:59 2005 New Revision: 17116 Modified: pypy/dist/pypy/translator/goal/richards.py Log: use time.time instead of time.clock, the latter can overflow producing confusing results Modified: pypy/dist/pypy/translator/goal/richards.py ============================================================================== --- pypy/dist/pypy/translator/goal/richards.py (original) +++ pypy/dist/pypy/translator/goal/richards.py Wed Aug 31 14:42:59 2005 @@ -399,9 +399,9 @@ def entry_point(): r = Richards() - startTime = time.clock() + startTime = time.time() result = r.run() - endTime = time.clock() + endTime = time.time() return result, startTime, endTime def main(entry_point = entry_point): From arigo at codespeak.net Wed Aug 31 15:06:40 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 31 Aug 2005 15:06:40 +0200 (CEST) Subject: [pypy-svn] r17117 - in pypy/dist/pypy: interpreter module/sys module/thread/test Message-ID: <20050831130640.3FFFC27B61@code1.codespeak.net> Author: arigo Date: Wed Aug 31 15:06:36 2005 New Revision: 17117 Modified: pypy/dist/pypy/interpreter/executioncontext.py pypy/dist/pypy/module/sys/vm.py pypy/dist/pypy/module/thread/test/support.py Log: threads: use the value specified in sys.setcheckinterval() as intended, to only release the GIL every nth bytecode. For now, the thread tests must force a sys.setcheckinterval(1). This is not particularly elegant and quite fragile until, and if, we have a way to release the GIL around system calls in py.py. Modified: pypy/dist/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/dist/pypy/interpreter/executioncontext.py (original) +++ pypy/dist/pypy/interpreter/executioncontext.py Wed Aug 31 15:06:36 2005 @@ -12,6 +12,7 @@ self.w_tracefunc = None self.w_profilefunc = None self.is_tracing = 0 + self.ticker = 0 self.compiler = space.createcompiler() def enter(self, frame): @@ -58,10 +59,13 @@ def bytecode_trace(self, frame): "Trace function called before each bytecode." - # First, call yield_thread() before each bytecode --- - # XXX this should be called only every N bytecodes, + # First, call yield_thread() before each Nth bytecode, # as selected by sys.setcheckinterval() - self.space.threadlocals.yield_thread() + ticker = self.ticker + if ticker <= 0: + self.space.threadlocals.yield_thread() + ticker = self.space.sys.checkinterval + self.ticker = ticker - 1 # Tracing logic if self.is_tracing or frame.w_f_trace is None: Modified: pypy/dist/pypy/module/sys/vm.py ============================================================================== --- pypy/dist/pypy/module/sys/vm.py (original) +++ pypy/dist/pypy/module/sys/vm.py Wed Aug 31 15:06:36 2005 @@ -53,13 +53,12 @@ return space.wrap(space.sys.recursionlimit) -checkinterval = 100 - def setcheckinterval(space, w_interval): """setcheckinterval(n) Tell the Python interpreter to check for asynchronous events every n instructions. This also affects how often thread switches occur.""" space.sys.checkinterval = space.int_w(w_interval) + space.getexecutioncontext().ticker = 0 def getcheckinterval(space): """getcheckinterval() -> current check interval; see setcheckinterval().""" Modified: pypy/dist/pypy/module/thread/test/support.py ============================================================================== --- pypy/dist/pypy/module/thread/test/support.py (original) +++ pypy/dist/pypy/module/thread/test/support.py Wed Aug 31 15:06:36 2005 @@ -26,3 +26,8 @@ time.sleep(0.002) return busywait """) + + space.appexec([], """(): + import sys + sys.setcheckinterval(1) + """) From pedronis at codespeak.net Wed Aug 31 15:34:45 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 31 Aug 2005 15:34:45 +0200 (CEST) Subject: [pypy-svn] r17118 - pypy/dist/pypy/annotation Message-ID: <20050831133445.3FA1827B3F@code1.codespeak.net> Author: pedronis Date: Wed Aug 31 15:34:44 2005 New Revision: 17118 Modified: pypy/dist/pypy/annotation/unaryop.py Log: don't attach is_type_of to a cached pbc. Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Wed Aug 31 15:34:44 2005 @@ -41,7 +41,7 @@ if moreargs: raise Exception, 'type() called with more than one argument' if obj.is_constant(): - r = immutablevalue(obj.knowntype) + r = SomePBC({obj.knowntype: True}) else: r = SomeObject() r.knowntype = type From arigo at codespeak.net Wed Aug 31 16:08:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 31 Aug 2005 16:08:14 +0200 (CEST) Subject: [pypy-svn] r17119 - pypy/dist/pypy/doc/image Message-ID: <20050831140814.54AEA27B51@code1.codespeak.net> Author: arigo Date: Wed Aug 31 16:08:11 2005 New Revision: 17119 Added: pypy/dist/pypy/doc/image/bpnn_callgraph.png (contents, props changed) pypy/dist/pypy/doc/image/bpnn_update.png (contents, props changed) pypy/dist/pypy/doc/image/bpnn_update_detail.png (contents, props changed) Log: Screen shots of the flowgraph viewer. Added: pypy/dist/pypy/doc/image/bpnn_callgraph.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/image/bpnn_update.png ============================================================================== Binary file. No diff available. Added: pypy/dist/pypy/doc/image/bpnn_update_detail.png ============================================================================== Binary file. No diff available. From cfbolz at codespeak.net Wed Aug 31 19:01:04 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 31 Aug 2005 19:01:04 +0200 (CEST) Subject: [pypy-svn] r17128 - pypy/dist/pypy/rpython/memory/test Message-ID: <20050831170104.C807827B51@code1.codespeak.net> Author: cfbolz Date: Wed Aug 31 19:01:04 2005 New Revision: 17128 Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py Log: small fix to the tests: make them pass on 64bit machines Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/dist/pypy/rpython/memory/test/test_gc.py Wed Aug 31 19:01:04 2005 @@ -14,6 +14,9 @@ from pypy.rpython.memory.lladdress import simulator from pypy.rpython.objectmodel import free_non_gc_object +import struct +INT_SIZE = struct.calcsize("l") + def setup_module(mod): def stdout_ignore_ll_functions(msg): strmsg = str(msg) @@ -51,7 +54,7 @@ j += 1 a.append(j) res = interpret(malloc_a_lot, []) - assert simulator.current_size - curr < 16000 + assert simulator.current_size - curr < 16000 * INT_SIZE / 4 print "size before: %s, size after %s" % (curr, simulator.current_size) def test_llinterp_tuples(self): @@ -67,7 +70,7 @@ j += 1 b.append((1, j, i)) res = interpret(malloc_a_lot, []) - assert simulator.current_size - curr < 16000 + assert simulator.current_size - curr < 16000 * INT_SIZE / 4 print "size before: %s, size after %s" % (curr, simulator.current_size) def test_global_list(self): @@ -90,7 +93,7 @@ return len("".join(lst)) res = interpret(concat, [100]) assert res == concat(100) - assert simulator.current_size - curr < 16000 + assert simulator.current_size - curr < 16000 * INT_SIZE / 4 class TestMarkSweepGCRunningOnLLinterp(TestMarkSweepGC): def setup_class(cls):